我目前有两个表,一个包含文档,另一个包含评级
doc_id | doc_groupid | doc_name | doc_time
然后
rating_id | rating_docid | rating_score
其中rating_score为-1或1。
我需要做的是使用单个查询来检索文档表WHERE groupid =#中的每一列,但也包含聚合评级的列。我可以使用
检索评级列表 SELECT rating_docid,
SUM(CASE WHEN rating_type = 1 THEN 1 ELSE 0 END ) AS UpVotes,
SUM(CASE WHEN rating_type = -1 THEN 1 ELSE 0 END) AS DownVotes
GROUP BY rating_docid
这给了我一份文件清单(只要他们被评级)以及他们有多少赞成或弃牌。我显然可以很容易地用
获取文档列表SELECT * FROM documents WHERE doc_groupid = #
但我不知道如何在没有子查询(使用JOIN或LEFT JOIN)的情况下执行此操作,我的理解太慢了。老实说,我不知道如何用子查询来做这个。
所以我的问题是:
谢谢!
答案 0 :(得分:0)
我想你需要像
这样的东西SELECT *
FROM documents d
LEFT JOIN
(
SELECT rating_docid,
SUM(CASE WHEN rating_type = 1 THEN 1 ELSE 0 END ) AS UpVotes,
SUM(CASE WHEN rating_type = -1 THEN 1 ELSE 0 END) AS DownVotes
FROM rating_table
GROUP BY rating_docid
)r ON (r.rating_docid = d.doc_id)
WHERE d.doc_groupid = ....
此外,如果将其更改为
,它可能会更快 SELECT *
FROM documents d
LEFT JOIN
(
SELECT rating_docid,
SUM(CASE WHEN rating_type = 1 THEN 1 ELSE 0 END ) AS UpVotes,
SUM(CASE WHEN rating_type = -1 THEN 1 ELSE 0 END) AS DownVotes
FROM rating_table
INNER JOIN documents d1 ON (d1.doc_id = rating_docid )
WHERE d1.doc_groupid =...
GROUP BY rating_docid
)r ON (r.rating_docid = d.doc_id)
WHERE d.doc_groupid = ....
答案 1 :(得分:0)
由于这两个连接可能看起来很奇怪但是,假设你的列可能已编入索引,应该表现得非常好。
SELECT d.doc_id, d.doc_name, d.doc_time
SUM(rd.rating_type) * -1 as DownVotes,
SUM(ru.rating_type) as UpVotes
FROM documents d
LEFT JOIN ratings rd ON d.doc_id = rd.rating_docid AND rd.rating_type < 0
LEFT JOIN ratings ru ON d.doc_id = ru.rating_docid AND rd.rating_type > 0
GROUP BY d.doc_id
您可能希望添加COALESCE http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_coalesce以防止查询在没有要加入的情况下返回NULL。
SELECT d.doc_id,
COALESCE(SUM(rd.rating_type), 0) * -1 as DownVotes,
COALESCE(SUM(ru.rating_type), 0) as UpVotes
FROM documents d ...
如果要检查的文档很多,我不建议使用子查询,因为每个文档执行另一个查询都意味着需要大量的开销。
答案 2 :(得分:0)
使用:
SELECT d.doc_id,
d.doc_name,
d.doc_time,
COALESCE(SUM(CASE WHEN r.rating_type = 1 THEN 1 ELSE 0 END), 0) AS upvotes,
COALESCE(SUM(CASE WHEN r.rating_type = -1 THEN 1 ELSE 0 END), 0) AS downvotes
FROM DOCUMENTS d
LEFT JOIN RATINGS r ON r.rating_docid = d.doc_id
WHERE d.doc_groupid = ?
GROUP BY d.doc_id, d.doc_name, d.doc_time
doc_time
对我来说很奇怪,让我觉得你可以有重复但有不同的时间价值......
JOIN(INNER和OUTER)不是子查询。为了使事情变得更复杂,子查询可能意味着:
SELECT子句中的查询(AKA子选择):
SELECT (SELECT col FROM TABLE) AS col2, ...
WHERE或HAVING子句中的查询:
WHERE col = (SELECT column FROM TABLE)
HAVING col IN (SELECT cols FROM TABLE)
JOIN中的查询(AKA派生表,内联视图):
LEFT JOIN (SELECT u.user,
COUNT(*) AS num
FROM TABLE u
GROUP BY u.user) x ON x.user = t.column
关于一个人比另一个人好,没有严格的规则,因为这一切都取决于:
所有真正重要的是工作是在必要时通过一张桌子进行的 - 最好是一个。