mysql - 如何在 MySQL SELECT 中按 'row sets' 分组?

标签 mysql

我有一个表 t,其中包含列 ab 的组合,它们分配了一个 idab 中的这些组合是重复的。对于每个这样的组合,我想确定所有的 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 13。我想获取组合 (A,u),(B,v) 的 ID 267 >。 ids 451 不同(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     |

View on DB Fiddle

关于mysql - 如何在 MySQL SELECT 中按 'row sets' 分组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58048150/

相关文章:

php - 如何从 php 脚本增加一个 sql 数据库

php - MYSQL 查询查找已审查的服务数量

mysql - 错误代码 : 1054. 'S.No' 中的未知列 'order clause'

mysql - 使用自动增量在 Mysql 数据库中设置 PK(string,int)

php - mysql 返回每个 user_id 的总行数

javascript - 通过单击按钮引用 li 的跨度

mysql - 为什么sql给出的结果不正确?

mysql - 如何故意创建长时间运行的 MySQL 查询

php - 如何使用HTML表单正确地将日期时间插入MYSQL数据库?

php - 成功订购后 Woocommerce 自定义库存更新