2013-08-25 117 views
0

我在尋找通過變量動態選擇不同列名的查詢。MySQL動態選擇列

假設我有一個包含我的「動態欄」我想要選擇的,是這樣的:

SELECT `ObjectID`,`ObjectLabel` FROM `modules_forms_objects` 
 
+----------+---------------+ 
| ObjectID | ObjectLabel | 
+----------+---------------+ 
|  71 | Join Date  | 
|  72 | Active  | 
+----------+---------------+ 

現在,我有一個表,該表是由被稱爲列如上所述的「ObjectID」。在這裏:

SELECT `data_id`,`71`,`72` FROM `7` 
 
+---------+---------------------+------+ 
| data_id | 71     | 72 | 
+---------+---------------------+------+ 
|  1 | 0000-00-00 00:00:00 | NULL | 
+---------+---------------------+------+ 

我想加入一個「值」列到第一個表,這將包含來自 匹配列在第二個表中的值。 (例如:對於ObjectID#72,該值將爲NULL)。

最後,我想我的結果是這樣的:

 
+----------+---------------+--------------------+ 
| ObjectID | ObjectLabel |  Value | 
+----------+---------------+--------------------+ 
|  71 | Join Date  |0000-00-00 00:00:00 | 
|  72 | Active  |  NULL | 
+----------+---------------+--------------------+ 

當我用傳統的「加入」我的每一行的所有列,這似乎有點沉重。

任何想法?非常感謝!

+0

,不是嗎? – itachi

回答

1

底座靜態​​查詢可能是這樣的

SELECT m.ObjectID, m.ObjectLabel, q.Value 
    FROM modules_forms_objects m LEFT JOIN 
(
    SELECT objectid, 
     CASE objectid 
      WHEN 71 THEN `71` 
      WHEN 72 THEN `72` 
     END value 
    FROM `7` t CROSS JOIN 
    (
    SELECT 71 objectid UNION ALL 
    SELECT 72 
) c 
) q 
    ON m.objectid = q.objectid 

的想法是先逆透視你的7表,然後外加入吧與modules_forms_objects

輸出:

 
| OBJECTID | OBJECTLABEL |    VALUE | 
-----------|-------------|---------------------| 
|  71 | Join Date | 0000-00-00 00:00:00 | 
|  72 |  Active |    (null) | 

這裏是SQLFiddle演示

如果你沒有幾十個幾十個7表列的我建議你堅持使用靜態查詢。


現在使用動態SQL同樣的事情

SET @sql = NULL, @sql1 = NULL, @sql2 = NULL; 

SELECT GROUP_CONCAT(
      CONCAT('WHEN ''', column_name, ''' THEN `', column_name, '`') 
     SEPARATOR ' ') 
    INTO @sql1 
    FROM INFORMATION_SCHEMA.COLUMNS 
WHERE table_schema = SCHEMA() 
    AND table_name = '7' 
    AND column_name LIKE '7%' 
GROUP BY table_name; 

SELECT GROUP_CONCAT(
      CONCAT('SELECT ''', column_name, ''' objectid') 
     SEPARATOR ' UNION ALL ') 
    INTO @sql2 
    FROM INFORMATION_SCHEMA.COLUMNS 
WHERE table_schema = SCHEMA() 
    AND table_name = '7' 
    AND column_name LIKE '7%' 
GROUP BY table_name; 

SET @sql = CONCAT(
'SELECT m.ObjectID, m.ObjectLabel, q.Value 
    FROM modules_forms_objects m LEFT JOIN 
(
    SELECT objectid, 
     CASE objectid ', @sql1, ' END value 
    FROM `7` t CROSS JOIN 
    (', @sql2, ' 
) c 
) q 
    ON m.objectid = q.objectid'); 

PREPARE stmt FROM @sql; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 

這裏是SQLFiddle演示

你有很多很多coulmns的
+0

謝謝。你知道這種動態是否有辦法嗎?如果我這樣做,我將不得不使用PHP來生成CASE語法,並且我試圖避免這種情況。 – Dan

+0

@丹不客氣。查看更新的答案。我剛剛展示瞭如何使用動態SQL來實現這一點。你可以將它包裝成一個存儲過程來簡化客戶端(php)方面的事情。 – peterm

+0

@丹如果你覺得它是你想要的,請考慮** [接受](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) ** 答案。 – peterm

0

USE SHOW COLUMNS FROM tab_name並使用FIELD屬性獲取相應的列。

0

這將使所有列名在特定表

SELECT 
     GROUP_CONCAT(COLUMN_NAME) 
FROM 
     INFORMATION_SCHEMA.COLUMNS 
WHERE 
     table_name = 'mytable'