---------------------------------
| table_one.col_a| table_one.fk |
---------------------------------
| A | 4 |
---------------------------------
| B | 4 |
---------------------------------
| C | 4 |
---------------------------------
---------------------------------
| table_two.col_b|table_two.fk |
---------------------------------
| E | 4 |
---------------------------------
| F | 4 |
---------------------------------
| G | 4 |
---------------------------------
| H | 4 |
---------------------------------
我正在寻找一个查询,当 fk 是通用外键时,它会输出类似这样的内容
A_E
B_F
C_G
_H
最佳答案
您需要使用变量来创建计数器字段:
例如
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 |
+-------+----+-----------+
在这里,您必须首先按分区字段排序,例如如果您希望每个 fk
的行号重置为 1,您必须首先按此顺序排序。然后您的下一个顺序决定了 RowNumber
的应用顺序。因此,如果您更改为:
ORDER BY fk, col_a DESC;
你会得到:
+-------+----+-----------+
| col_a | fk | RowNumber |
+-------+----+-----------+
| C | 4 | 1 |
| B | 4 | 2 |
| A | 4 | 3 |
+-------+----+-----------+
请注意,A 和 C 的行号现在不同
因此,如果您对两个表执行相同的操作,则可以加入 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;
如果您不知道哪个表将包含更多记录,由于 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;
<小时/>
编辑
感谢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;
关于mysql - SQL查询按时间顺序获取不同表的两列的组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19680781/