我需要构建一个复杂的查询,但我什至不知道从哪里开始。欢迎任何帮助。
我有一个用户表和一个游戏表,它们之间有 2 个多对多关系,表和相关列是:
- 用户:ID
- 游戏:id
- game_users_A:id、user_id、game_id。 (关系)
- game_users_B:id、user_id、game_id。 (B关系)
假设我选择了一个用户和一个关系,例如 user1,关系 A。 我想要获取所有其他用户,并根据 B 关系中有多少游戏与用户 1 的 A 关系中的游戏相匹配来对他们进行排序。
谢谢。我一直在尝试寻找类似的问题,但我什至不知道如何称呼我想要做的事情。
编辑。
感谢 Hayden 的帮助,我能够构建我需要的查询。 我只需要稍微调整一下他的:
他的查询将每个用户相互进行比较。这比我需要做的要多得多,对于大约 3000 个用户,它将返回超过 900000 行。 我只需要将登录到我的应用程序的用户与数据库中的每个其他用户进行比较,因此对于 N 个用户,我将获得 N - 1 行。
所以我只是添加了几个 WHERE 语句并更改了 ORDER BY。
假设发出请求的用户的 ID 为 3,并且希望查看与他的 A 关系中的游戏与 B 关系中的游戏相匹配的用户(而不是相反),查询如下:
SELECT U1.id, U2.id, SUM(GCol) AS matches
FROM users U1 JOIN users U2 ON U1.id <> U2.id
LEFT JOIN (SELECT A.user_id AS A_id, B.user_id as B_id, (A.id IS NOT NULL) AS GCol
FROM game_users_A A JOIN game_users_B B
ON A.game_id = B.game_id AND A.user_id <> B.user_id WHERE A.user_id = 3) G
ON U1.id = G.A_id AND U2.id = G.B_id
WHERE U1.id = 3
GROUP BY GCol, U1.id, U2.id
ORDER BY matches desc
再次感谢。
最佳答案
我使用这些表使用了一个小测试数据库,这就是我所拥有的。
我将其分为两个查询。第一个是将所有用户与所有其他用户进行匹配,这很简单:
SELECT U1.id, U2.id
FROM users U1 JOIN users U2 ON U1.id <> U2.id
ORDER BY U1.id, U2.id
第二个查询是将 B 组中的记录与 A 组中的记录进行匹配,其中比赛是相同的。这给了我:
SELECT A.user_id AS A_id, B.user_id as B_id
FROM game_users_A A JOIN game_users_B B
ON A.game_id = B.game_id AND A.user_id <> B.user_id
为了将这两个查询结合起来,我将第一个查询与第二个查询进行了左连接,因为对于任何一对用户,都可能没有匹配的游戏集。在这些情况下,第二个查询的结果将显示为 NULL 值。我们想要的是当这些出现时值为 1,因此如果您查看下面的查询,会发现值为
(A.id IS NOT NULL) AS GCol
使用它来求总和。如果有记录,则值为 1,否则为 NULL。当没有值时,总计仍然为空,但当有匹配时,总计会被汇总并显示。这给出了最终查询:
SELECT U1.id, U2.id, SUM(GCol)
FROM users U1 JOIN users U2 ON U1.id <> U2.id
LEFT JOIN (SELECT A.user_id AS A_id, B.user_id as B_id, (A.id IS NOT NULL) AS GCol
FROM game_users_A A JOIN game_users_B B
ON A.game_id = B.game_id AND A.user_id <> B.user_id) G
ON U1.id = G.A_id AND U2.id = G.B_id
GROUP BY GCol, U1.id, U2.id
ORDER BY U1.id, U2.id
我认为这就是您正在寻找的。p>
关于mysql 查询多对多关系中的匹配项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37664629/