我有一个表 t
,其中包含列 a
和 b
的组合,它们分配了一个 id
。 a
和 b
中的这些组合是重复的。对于每个这样的组合,我想确定所有的 id
。示例:
+------+------+------+
| id | a | b |
+------+------+------+
| 1 | A | x |
| 1 | B | y |
| 1 | C | z |
| 2 | A | u |
| 2 | B | v |
| 3 | A | x |
| 3 | B | y |
| 3 | C | z |
| 4 | A | x |
| 4 | B | y |
| 5 | A | x |
| 5 | B | y |
| 5 | C | z |
| 5 | D | n |
| 6 | A | u |
| 6 | B | v |
| 7 | A | u |
| 7 | B | v |
+------+------+------+
现在我想获取组合 (A,x),(B,y),(C,z) 的 ID
。我想获取组合 1
和 3
(A,u),(B,v)
的 ID 2
、6
和 7
>。 ids 4
和 5
与 1
不同(4
缺少一行,5
一行太多了),因此应该单独报告:
(A,x),(B,y),(C,z): 1,3
(A,u),(B,v): 2,6,7
(A,x),(B,y): 4
(A,x),(B,y),(C,z),(D,n): 5
这个分组如何查询MySQL?
设置示例表的 SQL 代码:
CREATE TABLE t (id int, a VARCHAR(4), b VARCHAR(4));
INSERT INTO t VALUES (1, 'A', 'x');
INSERT INTO t VALUES (1, 'B', 'y');
INSERT INTO t VALUES (1, 'C', 'z');
INSERT INTO t VALUES (2, 'A', 'u');
INSERT INTO t VALUES (2, 'B', 'v');
INSERT INTO t VALUES (3, 'A', 'x');
INSERT INTO t VALUES (3, 'B', 'y');
INSERT INTO t VALUES (3, 'C', 'z');
INSERT INTO t VALUES (4, 'A', 'x');
INSERT INTO t VALUES (4, 'B', 'y');
INSERT INTO t VALUES (5, 'A', 'x');
INSERT INTO t VALUES (5, 'B', 'y');
INSERT INTO t VALUES (5, 'C', 'z');
INSERT INTO t VALUES (5, 'D', 'n');
INSERT INTO t VALUES (6, 'A', 'u');
INSERT INTO t VALUES (6, 'B', 'v');
INSERT INTO t VALUES (7, 'A', 'u');
INSERT INTO t VALUES (7, 'B', 'v');
最佳答案
我们可以首先使用 Concat()
和 Group_Concat()
获取特定 id
中的所有组合。我们还可以确保 (a,b)
使用 Greatest()
和 Least( )
函数。 注意 如果 (b,a)
不应被视为与 (a,b)
相同,那么您可以摆脱对以下查询中的 Greatest()
和 Least()
。
在 Group_Concat()
中,我们也对它们进行排序,这样我们就不会得到两个单独的组合:(a,b), (c,d)
和 (c,d), (a,b)
。对于这两种情况,排序确保我们只得到:(a,b), (c,d)
。
最后,在派生表中使用此结果集,现在聚合所有具有相同组合集的 ID。
模式(MySQL v5.7)
CREATE TABLE t (id int, a VARCHAR(4), b VARCHAR(4));
INSERT INTO t VALUES (1, 'A', 'x');
INSERT INTO t VALUES (1, 'B', 'y');
INSERT INTO t VALUES (1, 'C', 'z');
INSERT INTO t VALUES (2, 'A', 'u');
INSERT INTO t VALUES (2, 'B', 'v');
INSERT INTO t VALUES (3, 'A', 'x');
INSERT INTO t VALUES (3, 'B', 'y');
INSERT INTO t VALUES (3, 'C', 'z');
INSERT INTO t VALUES (4, 'A', 'x');
INSERT INTO t VALUES (4, 'B', 'y');
INSERT INTO t VALUES (5, 'A', 'x');
INSERT INTO t VALUES (5, 'B', 'y');
INSERT INTO t VALUES (5, 'C', 'z');
INSERT INTO t VALUES (5, 'D', 'n');
INSERT INTO t VALUES (6, 'A', 'u');
INSERT INTO t VALUES (6, 'B', 'v');
INSERT INTO t VALUES (7, 'A', 'u');
INSERT INTO t VALUES (7, 'B', 'v');
查询#1
SELECT
dt.combinations,
GROUP_CONCAT(dt.id) AS ids
FROM
(
SELECT
GROUP_CONCAT(
DISTINCT
CONCAT('(', LEAST(a,b), ',', GREATEST(a,b), ')')
ORDER BY
CONCAT('(', LEAST(a,b), ',', GREATEST(a,b), ')') ASC) AS combinations,
id
FROM t
GROUP BY id
) dt
GROUP BY dt.combinations;
| combinations | ids |
| ----------------------- | ----- |
| (A,u),(B,v) | 2,6,7 |
| (A,x),(B,y) | 4 |
| (A,x),(B,y),(C,z) | 1,3 |
| (A,x),(B,y),(C,z),(D,n) | 5 |
关于mysql - 如何在 MySQL SELECT 中按 'row sets' 分组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58048150/