我有一个消息表,我想知道什么是最有效的查询来完成以下结果:
注意线程字段为空如果线程是第一条消息,则所有其他消息都链接到该线程的是emid
CREATE TABLE `messages` (
`emid` BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`emitter` BIGINT(20) NOT NULL,
`receiver` BIGINT(20) NOT NULL,
`thread` BIGINT(20) DEFAULT NULL,
`opened` TINYINT(4) DEFAULT 0,
`message` BLOB NOT NULL,
`timecard` DATETIME DEFAULT CURRENT_TIMESTAMP,
ADD CONSTRAINT `efk` FOREIGN KEY (`emitter`) REFERENCES `members` (`user_id`),
ADD CONSTRAINT `rfk` FOREIGN KEY (`receiver`) REFERENCES `members` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
我想获得给定接收器的第一行,包括其消息计数。比如说用户有4个未打开的消息(未读)和两个回复。我想得到这个帖子下收到的第一条消息以及双方的回复。起初我考虑过子查询,但看起来它会表现不佳。
以下为用户选择线程(receiver = id)
SELECT * FROM `messages` WHERE thread IS NULL AND receiver = 2 ORDER BY timecard DESC
这个获取给定线程下的消息计数
SELECT COUNT(*) FROM `messages` WHERE thread = 20
答案 0 :(得分:1)
加入你的两个问题:
SELECT m1.*, IFNULL(COUNT(m2.emid), 0) AS replies
FROM messages AS m1
LEFT JOIN messages AS m2 ON m2.thread = m1.emid
WHERE m1.thread is NULL
GROUP BY m1.emid
WHERE
子句仅选择表m1
中每个线程的起始消息。
LEFT JOIN
然后将其与该线程的所有回复相关联,使用thread
列将它们链接回原始邮件。我使用了LEFT JOIN
,因此不包含任何回复的邮件。
COUNT(m2.emid)
然后计算相关行的数量,这是线程中的回复数。 COUNT()
仅计算非空值;如果没有回复,LEFT JOIN
会将此列设置为NULL
,因此您将获得0
的计数。