2016-06-07 69 views
0

我想制作虚拟列。在list id主表中,我需要将虚拟列与'data'结合在一起。MySQL使用虚拟列加入表格

Table: columns 
+------+---------+-------------+ 
| [ID] | ID_USER | DATENAME | 
+------+---------+-------------+ 
| 1 | NULL | Description | 
+------+---------+-------------+ 
| 2 | NULL |  Cost | 
+------+---------+-------------+ 
| 3 | 2 | Width | 
+------+---------+-------------+ 

Table: list 
+----+-----------+------------+--------+ 
|[ID]| NAME | DATE | COLOR | 
+----+-----------+------------+--------+ 
| 1 | 234/2016 | 2016-06-06 | red | 
+----+-----------+------------+--------+ 
| 2 | 1000/2016 | 2016-06-07 | blue | 
+----+-----------+------------+--------+ 
| 3 | 3456/2016 | 2016-06-08 | yellow | 
+----+-----------+------------+--------+ 


Table: data 
+-----------+-----------+-------+ 
| ID_REPAIR | ID_COLUMN | VALUE | 
+-----------+-----------+-------+ 
|  1  |  1  | aaaa | 
+-----------+-----------+-------+ 
|  1  |  2  | 10$ | 
+-----------+-----------+-------+ 
|  2  |  1  | bbbb | 
+-----------+-----------+-------+ 
|  2  |  2  | 20$ | 
+-----------+-----------+-------+ 
|  3  |  1  | cccc | 
+-----------+-----------+-------+ 
|  3  |  2  | 30$ | 
+-----------+-----------+-------+ 


Result: 
+------+-----------+------------+--------+-------------+------+ 
| [ID] | NAME | DATE | COLOR | Description | Cost | 
+------+-----------+------------+--------+-------------+------+ 
| 1 | 234/2016 | 2016-06-06 | red |  aaaa | 10$ | 
+------+-----------+------------+--------+-------------+------+ 
| 2 | 1000/2016 | 2016-06-07 | blue |  bbbb | 20$ | 
+------+-----------+------------+--------+-------------+------+ 
| 3 | 3456/2016 | 2016-06-08 | yellow |  cccc | 30$ | 
+------+-----------+------------+--------+-------------+------+ 

在此查询,我得到的名字columns

SELECT * FROM `columns` WHERE `id_user` IS NULL 

而在PHP中保存的ID变量,但在测试中,我想生成唯一的第二列的表。在下面的代码我想Cost柱产生的结果,但始终是插入Description列:

SQL:

SELECT `list`.`id`, `name`, `date`, `color`, `data`.`value` 
FROM `list` 
INNER JOIN `data` ON `list`.`id` = `data`.`id_repair` WHERE `repair_data`.`id_column` = 2 

我不知道如何做INNER JOIN只有在id_column等于2

回答

1

SELECT返回的列数不能在执行时动态确定。列的数量以及分配给每列的数据类型和名称(或别名)必须在查询的SELECT列表中指定。所以让我们从这个开始。

为了有一个SQL语句,返回结果集如图所示,查询需要的形式为:

SELECT l.id 
     , l.name 
     , l.date 
     , l.color 
     , (expr1)  AS `Description` 
     , (expr2)  AS `Cost` 
    FROM list l 
    ... 

返回列。

至于表达expr1expr2你会使用返回DescriptionCost列,有一对夫妇的方法来展开实体属性值(EAV)模型回到规范的关系模型。

最容易理解但不一定是最好的选择是在SELECT列表中使用相关子查询。举例:

SELECT l.id 
     , l.name 
     , l.date 
     , l.color 
     , (SELECT d.value 
      FROM `data` d 
      WHERE d.id_repair = l.id 
      AND d.id_column = 1 
      ORDER BY d.value 
      LIMIT 1 
     )      AS `Description` 
     , (SELECT c.value 
      FROM `data` c 
      WHERE c.id_repair = l.id 
      AND c.id_column = 2 
      ORDER BY c.value 
      LIMIT 1 
     )      AS `Cost` 
     , (SELECT w.value 
      FROM `data` w 
      WHERE w.id_repair = l.id 
      AND w.id_column = 3 
      ORDER BY w.value 
      LIMIT 1 
     )      AS `Width` 
    FROM list l 
    ORDER BY l.id 

请注意,SELECT列表中的相关子查询可以返回不超过一行,并返回单个表达式。也就是说,它返回一个单个值值。


作为替代方案,我们可以使用外连接操作和条件聚合。例如:

SELECT l.id 
     , l.name 
     , l.date 
     , l.color 
     , MAX(IF(d.id_column=1,d.value,NULL)) AS `Description` 
     , MAX(IF(d.id_column=2,d.value,NULL)) AS `Cost` 
     , MAX(IF(d.id_column=3,d.value,NULL)) AS `Width` 
    FROM list l 
    LEFT 
    JOIN data d 
    ON d.id_repair = l.id 
    GROUP BY l.id, l.name, l.date, l.color 

如果我们需要返回的结果动态,具有不同的列数,并用于列的表达式,基于存储在数据库中的表,那么信息我们可以首先从数据库中获取信息,然后使用它来帮助我们构造实际的SQL语句,我们需要执行该语句才能获得最终结果。或者,尽可能多的使用实体属性值(EAV)模型的应用程序可以做到,我们甚至不会试图强制EAV模型回到规范化的关系模型中。我们只是让应用程序运行需要从表中检索信息的多个查询。基本上与应用程序向表中插入行的方式相反。