我有以下3张桌子:
我想构造一个执行以下操作的查询:
->从表 users 中选择尚未计划 type “ collection”
的 event 的所有用户->并且具有少于3种类型的 “ collection_reminder”
消息->谁不是 admin
我设法弄清楚了该查询的第一部分,但是当我尝试添加3表,进行计数等操作时,一切都变得有点像梨花了。
答案 0 :(得分:0)
这是一个可能完成任务的查询。每个需求在WHERE
子句中表示为条件,并在需要时使用相关子查询:
SELECT u.*
FROM users u
WHERE
NOT EXISTS (
SELECT 1
FROM events e
WHERE e.user_id = u.id AND e.type = 'collection'
)
AND (
SELECT COUNT(*)
FROM messages m
WHERE m.userid = u.id AND m.type = 'collection_reminder'
) <= 3
AND u.admin IS NULL
答案 1 :(得分:0)
我将在头顶尝试此操作,以期出现一些合奏问题,但想法如下。
您可以使用左联接过滤掉没有活动计划的人。在左侧的联接中,查询第二部分的元素将显示为null。
theString
现在,我不认为这是性能最高的方法,而是一种搜索包含3条以下消息的人的简单方法:
select * from users u
left join events e on e.user_id = u.id
where e.user_id is null
然后过滤不是管理员的人是最简单的:D
select * from users u
left join events e on e.user_id = u.id
where u.id in (
select COUNT(*) from messages m where m.user_id = u.id HAVING COUNT(*)>3;
)
and e.user_id is null
希望有帮助。
答案 2 :(得分:0)
这几乎是您的要求的直接翻译,按照您列出要求的顺序:
SELECT u.*
FROM users AS u
WHERE u.user_id NOT IN (SELECT user_id FROM events WHERE event_type = 'Collection')
AND u.user_id IN (
SELECT user_id
FROM messages
WHERE msg_type = 'Collection Reminder'
GROUP BY user_id
HAVING COUNT(*) < 3
)
AND u.admin = 0
或者,这可以完全通过联接来完成:
SELECT u.*
FROM users AS u
LEFT JOIN events AS e ON u.user_id = e.user_id AND e.event_type = 'Collection'
LEFT JOIN messages AS m ON u.user_id = m.user_id AND m.msg_type = 'Collection Reminder'
WHERE u.admin = 0
AND e.event_id IS NULL -- No event of type collection
GROUP BY u.user_id -- Note: you should group on all selected fields, and
-- some configuration of MySQL will require you do so.
HAVING COUNT(DISTINCT m.message_id) < 3 -- Less than 3 collection reminder messages
-- distinct is optional, but
-- if you were to remove the "no event" condition,
-- multiple events could multiply the message count.
;
答案 3 :(得分:0)
此查询使用联接来链接3个表,使用where子句和Group by筛选结果,并将结果限制为仅满足小于计数条件的对象。
SELECT a.id,
SUM(CASE WHEN b.type = 'collection' THEN 1 ELSE 0 END),
SUM(CASE WHEN c.type = 'collection_reminder' THEN 1 ELSE 0 END
FROM users a
left join events b on (b.user_id = a.id)
left join messages c on (c.user_id = a.id)
WHERE a.admin = false
GROUP BY a.id
HAVING SUM(CASE WHEN b.type = 'collection' THEN 1 ELSE 0 END) = 0
AND SUM(CASE WHEN c.type = 'collection_reminder' THEN 1 ELSE 0 END) < 3