我有一个名为 messages 的表,其中包含两列:userA 和 userB。
每个用户都有一个类型:typeA 或 typeB。
我想计算不同类型用户之间发送的消息数量的交叉表。用户也可以同时是 typeA 和 typeB。类型存储在不同的表中:(id:1, typeA), (id:2, typeB)
userA/userB | typeA | typeB
-----
typeA 2000 81348
-----
typeB 18348 12938
如何有效地做到这一点?假设我有 100000 条消息。如果我为 userA 执行第一次内部联接:在最坏的情况下我会得到 7*100000 条记录。现在,如果我为 userB 执行第二次内部联接:我将获得 7*7*100000 条记录。第二个连接查询需要很长时间。
有更好的方法吗?
最佳答案
SELECT src.type AS `UserA/UserB`, SUM(dest.type = 'typeA') AS typeA, SUM(dest.type = 'typeB') AS typeB
FROM messages AS msgsrc
JOIN users AS src ON msgsrc.userA = src.id
JOIN messages AS msgdest ON msgsrc.userA = msgdest.userB
JOIN users AS dest ON msgdest.userB = dest.id
GROUP BY `UserA/UserB`
如果有更多类型的用户,只需继续添加更多 SUM(dest.type = 'TypeX')
列即可。
如果您不需要单独列中的总和,您可以这样做:
SELECT src.type AS srcType, dest.type AS destType, COUNT(*) AS count
FROM messages AS msgsrc
JOIN users AS src ON msgsrc.userA = src.id
JOIN messages AS msgdest ON msgsrc.userA = msgdest.userB
JOIN users AS dest ON msgdest.userB = dest.id
GROUP BY srcType, destType
这不需要修改来处理更多类型,并且可能会更有效,因为它不必生成那么大的中间表。
关于mysql - 在 MySQL 中计算交叉表的有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27852517/