MySQL数据透视表在1到n之间的关系

时间:2016-08-15 07:18:44

标签: mysql join

我有这样的数据 table master_item

+-------+---------+
|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  |     |     |
+-------+---------+-----+-----+-----+-----+-----+-----+-----+

产生此结果的查询是什么?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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