如果您知道最大数为12,则可以使用MAX
和CASE
获取每个附件的行号。
SELECT
I.Id issue_id,
I.title,
MAX(CASE WHEN d.row_number = 1 THEN D.attachment END) attachment1,
MAX(CASE WHEN d.row_number = 2 THEN D.attachment END) attachment2,
MAX(CASE WHEN d.row_number = 3 THEN D.attachment END) attachment3,
MAX(CASE WHEN d.row_number = 4 THEN D.attachment END) attachment4,
MAX(CASE WHEN d.row_number = 5 THEN D.attachment END) attachment5,
MAX(CASE WHEN d.row_number = 6 THEN D.attachment END) attachment6,
MAX(CASE WHEN d.row_number = 7 THEN D.attachment END) attachment7,
MAX(CASE WHEN d.row_number = 8 THEN D.attachment END) attachment8,
MAX(CASE WHEN d.row_number = 9 THEN D.attachment END) attachment9,
MAX(CASE WHEN d.row_number = 10 THEN D.attachment END) attachment10,
MAX(CASE WHEN d.row_number = 11 THEN D.attachment END) attachment11,
MAX(CASE WHEN d.row_number = 12 THEN D.attachment END) attachment12
FROM Issues I
LEFT JOIN (
SELECT
a.issue_id,
@running:=if(@previous=a.issue_id,@running,0) + 1 as row_number,
@previous:=a.issue_id,
a.attachment
FROM Attachments a
JOIN (SELECT @previous := 0) r
ORDER BY a.issue_id, a.attachment
) D ON I.ID = D.issue_id
GROUP BY I.Id, I.Title
这里是SQL Fiddle。
我必须进行编辑才能使每组的rownumber重置。应该现在工作。另外,per @ spencer7593的好评,我已经稍微更新了这个查询。
- 编辑 -
针对OP的大约需要动态结果的评论,这应该工作:
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'MAX(IF(d.row_number = ', d.row_number, ',D.attachment,NULL)) AS attachment', d.row_number)
) INTO @sql
FROM Issues I
LEFT JOIN (
SELECT
a.issue_id,
@running:=if(@previous=a.issue_id,@running,0) + 1 as row_number,
@previous:=a.issue_id,
a.attachment
FROM Attachments a
JOIN (SELECT @previous := 0) r
ORDER BY a.issue_id, a.attachment
) D ON I.ID = D.issue_id
;
SET @sql = CONCAT('SELECT I.Id issue_id,
I.title, ', @sql, '
FROM Issues I
LEFT JOIN (
SELECT
a.issue_id,
@running:=if(@previous=a.issue_id,@running,0) + 1 as row_number,
@previous:=a.issue_id,
a.attachment
FROM Attachments a
JOIN (SELECT @previous := 0) r
ORDER BY a.issue_id, a.attachment
) D ON I.ID = D.issue_id
GROUP BY I.Id, I.Title');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
这里是SQL Fiddle。
+1。在内联视图中重新命名'@previous:= NULL'为别名为'r'是很好的,以便将语句与存储在变量@previous中的任何先前值隔离。在内联视图别名为“d”时,SELECT列表中的第一个a.issue_id是多余的;可以在设置@previous:= a.issue_id的行上分配列别名'issue_id'。另外,在内联视图中的ORDER BY会使语句更具确定性,因为附件将以指定的顺序返回,而不是允许MySQL以任意顺序返回它们。 – spencer7593 2013-02-09 01:55:36
@ spencer7593 - 精彩评论,非常感谢!我从以前的版本错误地留下了curRow :)我编辑了我的回复 - 再次感谢! – sgeddes 2013-02-09 02:05:23
@sgeddes - 谢谢!这很棒,满足了我的迫切需求。接下来,我将不得不弄清楚如何通过使用按ID分组的附件的最大数量来获得相同的结果(这就是我如何从12开始)。因此,当一个id的最大潜在附件更改时,列也会动态更改。如果你知道如何做到这一点,它将完全解决我的使用案例! – 2013-02-15 00:56:53