MySQL:Union,Count和Group By

时间:2011-02-10 00:13:21

标签: sql mysql count group-by union

(
SELECT root_tags.tag_id, root_tags.tag_name, COUNT( root_tagged.pg_id )
FROM root_tags

LEFT JOIN root_tagged ON ( root_tagged.tag_id = root_tags.tag_id )
LEFT JOIN root_pages ON ( root_pages.pg_id =  root_tagged.pg_id )
LEFT JOIN root_granted ON ( root_granted.pg_id =  root_tagged.pg_id )

WHERE root_pages.parent_id = '5'
AND root_granted.mem_id = '3'

GROUP BY root_tags.tag_id
ORDER BY 3 DESC
)

UNION
(
SELECT root_tags.tag_id, root_tags.tag_name, COUNT( root_tagged.pg_id )
FROM root_tags

LEFT JOIN root_tagged ON ( root_tagged.tag_id = root_tags.tag_id )
LEFT JOIN root_pages ON ( root_pages.pg_id =  root_tagged.pg_id )

WHERE root_pages.parent_id = '5'
AND NOT EXISTS (
    SELECT *
    FROM root_granted
    WHERE root_granted.pg_id =  root_pages.pg_id )

GROUP BY root_tags.tag_id
ORDER BY 3 DESC
)

上面的查询返回如下所示的结果

tag_id  tag_name                COUNT(root_tags.tag_id)
16      expert-category-c       2
14      expert-category-a       1
15      expert-category-b       1
16      expert-category-c       1

正如您所看到的那样重复tag_id 16,如何重写查询以使tag_id 16的计数编号为3,我的意思是我希望查询返回像这样的结果,

tag_id  tag_name                COUNT(root_tags.tag_id)
16      expert-category-c       3
14      expert-category-a       1
15      expert-category-b       1

我尝试使用此查询,但它返回错误...

(
SELECT root_tags.tag_id, root_tags.tag_name, COUNT( root_tagged.pg_id )
FROM root_tags

LEFT JOIN root_tagged ON ( root_tagged.tag_id = root_tags.tag_id )
LEFT JOIN root_pages ON ( root_pages.pg_id =  root_tagged.pg_id )
LEFT JOIN root_granted ON ( root_granted.pg_id =  root_tagged.pg_id )

WHERE root_pages.parent_id = '5'
AND root_granted.mem_id = '3'

)

UNION
(
SELECT root_tags.tag_id, root_tags.tag_name, COUNT( root_tagged.pg_id )
FROM root_tags

LEFT JOIN root_tagged ON ( root_tagged.tag_id = root_tags.tag_id )
LEFT JOIN root_pages ON ( root_pages.pg_id =  root_tagged.pg_id )

WHERE root_pages.parent_id = '5'
AND NOT EXISTS (
    SELECT *
    FROM root_granted
    WHERE root_granted.pg_id =  root_pages.pg_id )
)

GROUP BY root_tags.tag_id
ORDER BY 3 DESC

你能告诉我如何使这项工作吗?

感谢。

1 个答案:

答案 0 :(得分:4)

在分析您的实际查询时,下面将进一步给出更好的查询。

您可以使用UNION ALL而不是UNION合并这两个查询(以保留重复项),然后在整个集合中运行GROUP BY。

SELECT tag_id, tag_name, SUM(CountTags) as CountTags
FROM
(
SELECT root_tags.tag_id, root_tags.tag_name, COUNT( root_tagged.pg_id ) CountTags
FROM root_tags

LEFT JOIN root_tagged ON ( root_tagged.tag_id = root_tags.tag_id )
LEFT JOIN root_pages ON ( root_pages.pg_id =  root_tagged.pg_id )
LEFT JOIN root_granted ON ( root_granted.pg_id =  root_tagged.pg_id )

WHERE root_pages.parent_id = '5'
AND root_granted.mem_id = '3'

GROUP BY root_tags.tag_id

UNION ALL

SELECT root_tags.tag_id, root_tags.tag_name, COUNT( root_tagged.pg_id ) CountTags
FROM root_tags

LEFT JOIN root_tagged ON ( root_tagged.tag_id = root_tags.tag_id )
LEFT JOIN root_pages ON ( root_pages.pg_id =  root_tagged.pg_id )

WHERE root_pages.parent_id = '5'
AND NOT EXISTS (
    SELECT *
    FROM root_granted
    WHERE root_granted.pg_id =  root_pages.pg_id )

GROUP BY root_tags.tag_id
) SQ
GROUP BY tag_id, tag_name
ORDER BY CountTags DESC

由于您的WHERE子句会对root_granted和root_pages进行过滤,因此这些子句实际上是INNER JOIN。您还可以使用EXISTS测试来模拟UNION的第一部分,假设每个root_pages记录永远不会有超过1个root_granted记录。

SELECT root_tags.tag_id, root_tags.tag_name, COUNT( root_tagged.pg_id ) CountTags
FROM root_tags
INNER JOIN root_tagged ON ( root_tagged.tag_id = root_tags.tag_id )
INNER JOIN root_pages ON ( root_pages.pg_id =  root_tagged.pg_id )
WHERE root_pages.parent_id = '5'
AND (NOT EXISTS (
    SELECT *
    FROM root_granted
    WHERE root_granted.pg_id =  root_pages.pg_id )
OR EXISTS (
    SELECT *
    FROM root_granted
    WHERE root_granted.pg_id =  root_pages.pg_id AND root_granted.mem_id = '3'))
GROUP BY root_tags.tag_id, root_tags.tag_name
ORDER BY CountTags DESC

由于not existsexists是互斥的,因此您可以将OR用于单个查询。

相关问题