2016-08-15 132 views
3

我有这样 表数据master_itemMySQL的透视表到n的关系

 
+-------+---------+ 
|item_id|item_name| 
+-------+---------+ 
| 001 | Car A | 
| 002 | Car B | 
+-------+---------+ 

和关系到表过程

 
+-------+--------+ 
|proc_id|proc_seq| 
+-------+--------+ 
| 001 | 1 | 
| 001 | 2 | 
| 001 | 3 | 
| 001 | 4 | 
| 001 | 5 | 
| 002 | 1 | 
| 002 | 2 | 
| 002 | 3 | 
+-------+--------+ 

,我想导致像这样,当我选择ITEM_ID = 001

 
+-------+---------+-----+-----+-----+-----+-----+-----+-----+ 
|item_id|item_name|proc1|proc2|proc3|proc4|proc5|proc6|proc7| 
+-------+---------+-----+-----+-----+-----+-----+-----+-----+ 
| 001 | Car A | 1 | 2 | 3 | 4 | 5 |  |  | 
+-------+---------+-----+-----+-----+-----+-----+-----+-----+ 

什么是查询产生这个结果?

+0

采用,而不是由数据透视表查询做这个简单的查询。并在应用程序级别 – 1000111

回答

2

问题在于PIVOT TABLE类别。

在这里,您可以通过下面给出的查询实现你的结果:

SET @sql := ''; 
SELECT 
CONCAT('SELECT 
MI.item_id, 
MI.item_name,', 
GROUP_CONCAT('MAX(CASE WHEN P.proc_seq =', P.proc_seq ,' THEN P.proc_seq END) AS ', 'proc',P.proc_seq,' '), 
'FROM master_item MI 
INNER JOIN process P ON MI.item_id = P.proc_id 
WHERE MI.item_id = 1 
GROUP BY P.proc_id') INTO @sql 
FROM master_item MI 
INNER JOIN process P ON MI.item_id = P.proc_id 
WHERE item_id = 1 
GROUP BY P.proc_id; 


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

WORKING DEMO

但就像我说的,最好做这样的工作在应用逻辑。否则,通过单独的MySQL来完成它将非常麻烦。

编辑:

为了得到结果每个item_id

SET @sql := ''; 
SELECT 
CONCAT('SELECT 
MI.item_id, 
MI.item_name,', 
GROUP_CONCAT('MAX(CASE WHEN P.proc_seq =', P.proc_seq ,' THEN P.proc_seq END) AS ', 'proc',P.proc_seq,' '), 
'FROM master_item MI 
INNER JOIN process P ON MI.item_id = P.proc_id 
GROUP BY P.proc_id') INTO @sql 
FROM master_item MI 
INNER JOIN process P ON MI.item_id = P.proc_id 

WHERE 
    item_id = (
     SELECT 
      maxProcId.proc_id 
     FROM 
      (
       SELECT 
        proc_id, 
        COUNT(proc_seq) total 
       FROM process 
       GROUP BY proc_id 
       ORDER BY total DESC 
       LIMIT 1 
      ) AS maxProcId 
    ) 
GROUP BY 
    P.proc_id; 


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

Demonstrated here

+0

伟大的,但名称和ID始终为1和CAR A和进程是随机的 – NeoS

+0

你不想要结果'item_id = 1' ? – 1000111

+0

非常棒..它的作品..很多.. – NeoS

0

随着Group_concat,然后拆分数据单独列你可以做到这一点

SELECT t1.*, 
     SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(t2.proc_seq), ',', 1), ',', -1) AS proc1, 
     SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(t2.proc_seq), ',', 2), ',', -1) AS proc2, 
     SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(t2.proc_seq), ',', 3), ',', -1) AS proc3, 
     SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(t2.proc_seq), ',', 4), ',', -1) AS proc4, 
     SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(t2.proc_seq), ',', 5), ',', -1) AS proc5 
FROM tt1 t1 
LEFT JOIN tt2 t2 ON t1.item_id=t2.proc_id 
+0

thx @ashkufaraz为您的答复做其余的工作,但我希望结果显示在每个列按照过程中,没有作出一个在列程序 – NeoS

+0

我更新我的答案,你可以做到这一点与子string_index – ashkufaraz

+0

伟大的,但过程不准确时,seq是随机的..必须首先索引 – NeoS