我有一个名为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条记录。第二次连接查询需要很长时间。
有更好的方法吗?
答案 0 :(得分:0)
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
这不需要修改来处理更多类型,并且可能更有效,因为它不必生成大的中间表。