您需要使用变量来创建计数器字段:
例如
SELECT col_a,
fk,
@r:= CASE WHEN @FK = fk THEN @r + 1 ELSE 1 END AS RowNumber,
@fk:= fk
FROM table_one,
(SELECT @fk:= 0) fk,
(SELECT @r:= 0) r
ORDER BY fk, col_a;
将返回
+-------+----+-----------+
| col_a | fk | RowNumber |
+-------+----+-----------+
| A | 4 | 1 |
| B | 4 | 2 |
| C | 4 | 3 |
+-------+----+-----------+
在这里,您必须首先按分区字段排序,例如,如果您希望每个行号重置为 1,fk
您必须首先按此排序。然后您的下一个订单决定了RowNumber
应用的顺序。因此,如果您更改为:
ORDER BY fk, col_a DESC;
你会得到:
+-------+----+-----------+
| col_a | fk | RowNumber |
+-------+----+-----------+
| C | 4 | 1 |
| B | 4 | 2 |
| A | 4 | 3 |
+-------+----+-----------+
注意 A 和 C 的 RowNumbers 现在不同了
因此,如果您对两个表执行相同的操作,则可以加入fk
和RowNumber
:
SELECT b.fk, CONCAT(COALESCE(a.col_a, ''), '_', COALESCE(b.Col_b, '')) AS ColA_ColB
FROM ( SELECT col_b,
fk,
@r:= CASE WHEN @FK = fk THEN @r + 1 ELSE 1 END AS RowNumber,
@fk:= fk
FROM table_two,
(SELECT @fk:= 0) fk,
(SELECT @r:= 0) r
ORDER BY fk, col_b
) b
LEFT JOIN
( SELECT col_a,
fk,
@r:= CASE WHEN @FK = fk THEN @r + 1 ELSE 1 END AS RowNumber,
@fk:= fk
FROM table_one,
(SELECT @fk:= 0) fk,
(SELECT @r:= 0) r
ORDER BY fk, col_a
) a
ON b.fk = a.fk
AND b.RowNumber = a.RowNumber;
SQL Fiddle 示例
如果您不知道哪个表将包含更多记录,因为 MySQL 不支持完全连接,查询会变得有点复杂,您需要UNION ALL
合并数据集:
SELECT a.fk,
a.RowNumber,
CONCAT(MAX(CASE WHEN TableSource = 1 THEN Col ELSE '' END),
'_',
MAX(CASE WHEN TableSource = 2 THEN Col ELSE '' END)) AS Col_AB
FROM (( SELECT col_b AS Col,
fk,
@r:= CASE WHEN @FK = fk THEN @r + 1 ELSE 1 END AS RowNumber,
@fk:= fk,
2 AS TableSource
FROM table_two,
(SELECT @fk:= 0) fk,
(SELECT @r:= 0) r
ORDER BY fk, col_b
)
UNION ALL
( SELECT col_a,
fk,
@r:= CASE WHEN @FK = fk THEN @r + 1 ELSE 1 END AS RowNumber,
@fk:= fk,
1 AS TableSource
FROM table_one,
(SELECT @fk:= 0) fk,
(SELECT @r:= 0) r
ORDER BY fk, col_a
)) a
GROUP BY a.fk, a.RowNumber;
SQL Fiddle 示例
编辑
感谢Andriy M,这两个查询可以整理如下:
加入方法:
SELECT b.fk, CONCAT(COALESCE(a.col_a, ''), '_', COALESCE(b.Col_b, '')) AS ColA_ColB
FROM ( SELECT col_b,
@r:= (@fk = fk) * @r + 1 AS RowNumber,
@fk:= fk AS fk
FROM table_two,
(SELECT @fk:= 0, @r:= 0) r
ORDER BY fk, col_b
) b
LEFT JOIN
( SELECT col_a,
@r:= (@fk = fk) * @r + 1 AS RowNumber,
@fk:= fk AS fk
FROM table_one,
(SELECT @fk:= 0, @r:= 0) r
ORDER BY fk, col_a
) a
ON b.fk = a.fk
AND b.RowNumber = a.RowNumber;
联合方法:
SELECT a.fk,
a.RowNumber,
CONCAT(MAX(CASE WHEN TableSource = 1 THEN Col ELSE '' END),
'_',
MAX(CASE WHEN TableSource = 2 THEN Col ELSE '' END)) AS Col_AB
FROM (( SELECT col_b AS Col,
@r:= (@fk = fk) * @r + 1 AS RowNumber,
@fk:= fk AS fk,
2 AS TableSource
FROM table_two,
(SELECT @fk:= 0, @r:= 0) s
ORDER BY fk, col_b
)
UNION ALL
( SELECT col_a,
@r:= (@fk = fk) * @r + 1 AS RowNumber,
@fk:= fk AS fk,
1 AS TableSource
FROM table_one,
(SELECT @fk:= 0, @r:= 0) s
ORDER BY fk, col_a
)) a
GROUP BY a.fk, a.RowNumber;
SQL Fiddle 上的示例