考虑以下MySQL数据库中的表:
entries:
creator_id INT
entry TEXT
is_expired BOOL
other:
creator_id INT
entry TEXT
userdata:
creator_id INT
name VARCHAR
etc...
在entries
和other
中,1个创建者可以有多个条目。 userdata
表仅供我阅读(放在其他数据库中)。
我想要获得以下SELECT结果:
+------------+---------+---------+-------+
| creator_id | entries | expired | other |
+------------+---------+---------+-------+
| 10951 | 59 | 55 | 39 |
| 70887 | 41 | 34 | 108 |
| 88309 | 38 | 20 | 102 |
| 94732 | 0 | 0 | 86 |
...其中entries
等于SELECT COUNT(entry) FROM entries GROUP BY creator_id
,
expired
等于SELECT COUNT(entry) FROM entries WHERE is_expired = 0 GROUP BY creator_id
和
other
等于SELECT COUNT(entry) FROM other GROUP BY creator_id
。
我需要这个结构,因为在执行此SELECT之后,我需要在“userdata”表中查找用户数据,我计划使用INNER JOIN并选择所需的列。
我通过在列中选择“NULL”解决了这个问题,该列不适用于给定的SELECT:
SELECT
creator_id,
COUNT(any_entry) as entries,
COUNT(expired_entry) as expired,
COUNT(other_entry) as other
FROM (
SELECT
creator_id,
entry AS any_entry,
NULL AS expired_entry,
NULL AS other_enry
FROM entries
UNION
SELECT
creator_id,
NULL AS any_entry,
entry AS expired_entry,
NULL AS other_enry
FROM entries
WHERE is_expired = 1
UNION
SELECT
creator_id,
NULL AS any_entry,
NULL AS expired_entry,
entry AS other_enry
FROM other
) AS tTemp
GROUP BY creator_id
ORDER BY
entries DESC,
expired DESC,
other DESC
;
我遗漏了INNER JOIN并故意从userdata
表中选择了其他列(我的问题是将3个SELECT组合成1个)。
similar question的解决方案不会返回entries
和expired
为0
的行。
感谢您的时间。
答案 0 :(得分:1)
这应该有效(假设所有creator_id
出现在userdata
表中。
SELECT userdata.creator_id, COALESCE(entries_count_,0) AS entries_count, COALESCE(expired_count_,0) AS expired_count, COALESCE(other_count_,0) AS other_count
FROM userdata
LEFT OUTER JOIN
(SELECT creator_id, COUNT(entry) AS entries_count_
FROM entries
GROUP BY creator_id) AS entries_q
ON userdata.creator_id=entries_q.creator_id
LEFT OUTER JOIN
(SELECT creator_id, COUNT(entry) AS expired_count_
FROM entries
WHERE is_expired=0
GROUP BY creator_id) AS expired_q
ON userdata.creator_id=expired_q.creator_id
LEFT OUTER JOIN
(SELECT creator_id, COUNT(entry) AS other_count_
FROM other
GROUP BY creator_id) AS other_q
ON userdata.creator_id=other_q.creator_id;
答案 1 :(得分:0)
基本上,你所做的事情对我来说是正确的。
我会通过
重写如下SELECT entries.creator_id
, any_entry
, expired_entry
, other_entry
FROM (
SELECT creator_id, COUNT(entry) AS any_entry,
FROM entries
GROUP BY creator_id
) entries
LEFT OUTER JOIN (
SELECT creator_id, COUNT(entry) AS expired_entry,
FROM entries
WHERE is_expired = 1
GROUP BY creator_id
) expired ON expired.creator_id = entries.creator_id
LEFT OUTER JOIN (
SELECT creator_id, COUNT(entry) AS other_entry
FROM other
GROUP BY creator_id
) other ON other.creator_id = entries.creator_id
答案 2 :(得分:0)
怎么样
SELECT creator_id,
(SELECT COUNT(*)
FROM entries e
WHERE e.creator_id = main.creator_id AND
e.is_expired = 0) AS entries,
(SELECT COUNT(*)
FROM entries e
WHERE e.creator_id = main.creator_id AND
e.is_expired = 1) as expired,
(SELECT COUNT(*)
FROM other
WHERE other.creator_id = main.creator_id) AS other,
FROM entries main
GROUP BY main.creator_id;