2016-06-07 87 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模型回到規範化的關係模型中。我們只是讓應用程序運行需要從表中檢索信息的多個查詢。基本上與應用程序向表中插入行的方式相反。