一个查询中有多个GROUP_CONCAT

时间:2013-08-22 08:50:10

标签: mysql sql

我有两张桌子:

CREATE TABLE instructions (
 `id_instruction` INT(11),
 `id_step` INT(11)
);

CREATE TABLE steps (
 `id_instruction` INT(11),
 `id_step` INT(11),
 `val` VARCHAR(255)
);

一个表包含指令,另一个表包含步骤。每条指令可能有很多步骤。现在,数据是:

INSERT INTO instructions (`id_instruction`, `id_step`) VALUES (1, 0), (1, 1), (1, 2);
INSERT INTO steps (`id_instruction`, `id_step`, `val` ) VALUES (1, 0, 'One'), (1, 0, 'Two'), (1, 0, 'Three'); /* step 0 */
INSERT INTO steps (`id_instruction`, `id_step`, `val` ) VALUES (1, 1, 'Five'), (1, 1, 'Six'), (1, 1, 'Seven'); /* step 1 */
INSERT INTO steps (`id_instruction`, `id_step`, `val` ) VALUES (1, 2, 'Eight'), (1, 2, 'Nine'), (1, 2, 'Ten'); /* step 2 */

对于每个指令,我希望有两个连接 - 一个连接来自val列的值用于零步骤,另一个连接来自同一列的值用于指令的最大步骤。我知道如何获得最大的一步以及如何进行单组连接,但是尝试进行两次连接,我得到了重复。现在,我的查询如下所示:

SELECT maxstep, i.id_instruction, i.id_step, GROUP_CONCAT(s.val) AS val_0 
FROM instructions i
INNER JOIN (
 SELECT MAX(id_step) AS maxstep, id_instruction  FROM instructions i
 GROUP BY i.id_instruction  
) i2 ON i2.id_instruction = i.id_instruction 
LEFT JOIN steps s ON s.id_instruction = i.id_instruction AND s.id_step = i.id_step 
GROUP BY i.id_instruction, i.id_step

它只是连接每对指令步骤的值。但我希望还有一个连接,它也可以连接maxstep的值。期望的结果应如下所示:

| maxstep | id_instruction |      val_0     |      val_1       |
|    2    |       1        | One,Two, Three | Eight, Nine, Ten |

PS。我加入而不只是MAX和分组,因为我想在额外的连接中使用它的值来进一步连接。

2 个答案:

答案 0 :(得分:1)

您尝试做的事情称为旋转。在MySQL中没有内置函数,但你可以这样做:

SELECT maxstep, id_instruction, 
MAX(CASE id_step WHEN 0 THEN val END) AS val_0,
MAX(CASE id_step WHEN 1 THEN val END) AS val_1,
MAX(CASE id_step WHEN 2 THEN val END) AS val_2
FROM (
SELECT maxstep, i.id_instruction, i.id_step, GROUP_CONCAT(s.val) AS val
FROM instructions i
INNER JOIN (
 SELECT MAX(id_step) AS maxstep, id_instruction  FROM instructions i
 GROUP BY i.id_instruction  
) i2 ON i2.id_instruction = i.id_instruction 
LEFT JOIN steps s ON s.id_instruction = i.id_instruction AND s.id_step = i.id_step 
GROUP BY i.id_instruction, i.id_step
) sq
GROUP BY maxstep, id_instruction

结果:

maxstep id_instruction  val_0           val_1           val_2
-----------------------------------------------------------------
2           1           One,Two,Three   Five,Six,Seven  Ten,Eight,Nine

答案 1 :(得分:1)

通过稍微更改查询以使内连接仅获得最高步骤,并通过将外部查询设置为仅获取id_step = 0,您可以获得所需内容。

SELECT maxstep, i.id_instruction,GROUP_CONCAT(s.val) AS val_0, val_1 
FROM instructions i
INNER JOIN (
 SELECT MAX(ins.id_step) AS maxstep, ins.id_instruction, GROUP_CONCAT(st.val) as val_1 FROM instructions ins
 LEFT JOIN steps st ON st.id_instruction = ins.id_instruction AND st.id_step = ins.id_step 
 where (ins.id_instruction, ins.id_step) in (select id_instruction, max(id_step) from instructions group by id_instruction)
 GROUP BY ins.id_instruction, ins.id_step  
 order by maxstep, ins.id_instruction, st.val
) 
i2 ON i2.id_instruction = i.id_instruction 
LEFT JOIN steps s ON s.id_instruction = i.id_instruction AND s.id_step = i.id_step 
where i.id_step=0
GROUP BY i.id_instruction, i.id_step;

带有扩展数据的查询结果现在看起来像

| maxstep | id_instruction |      val_0     |      val_1       |
|    2    |       1        |  One,Two,Three |  Eight,Nine,Ten  |
|    3    |       2        |  One,Two,Three |     21,22,23     |