是否有可能同时获得结果和结果的计数? (根据结果计数过滤结果)

时间:2013-06-11 12:11:16

标签: mysql sql

我有一个查询,我希望同时获得结果和结果的计数。对结果的过滤很复杂,所以我不能简单地使用子查询技巧,如other question中所示。我的最终目标是根据结果计数过滤结果。

示例:

SELECT id, related_info, count(related_info) 
FROM my_table 
WHERE <complex filtering on related_info here>;

结果应如下所示:   

id | related_info |  count(related_info)|
1  |         info1|                    3|
1  |         info2|                    3|
1  |         info3|                    3|
2  |         info1|                    2|
2  |         info2|                    2|

我的最终目标是根据计数过滤结果,例如:

SELECT id, related_info, count(related_info) 
FROM my_table 
WHERE <complex filtering on related_info here> having count(related_info) >=3;`

结果应如下所示:   

id | related_info |  count(related_info)|
1  |         info1|                    3|
1  |         info2|                    3|
1  |         info3|                    3|
(过滤id 2的结果)

我无法使用group by,因为我想获得所有结果。我不能使用子查询,因为它意味着要执行两次复杂的过滤。

我没有看到任何方法通过单个查询执行此操作。

2 个答案:

答案 0 :(得分:1)

以下查询:

SELECT id, related_info, count(related_info)
FROM my_table
WHERE <complex filtering on related_info here>
group by id, related_info with rollup

会产生如下结果:

id | related_info |  count(related_info)|
1  |         info1|                    1|
1  |         info2|                    1|
1  |         info3|                    1|
1  |         NULL |                    3|

rollup添加了一个包含摘要信息的额外行。

在大多数数据库中,解决方案很简单:

SELECT id, related_info, count(related_info) over (partition by id)
FROM my_table
WHERE <complex filtering on related_info here>

在没有重复where子句的情况下获取MySQL 中的等效内容具有挑战性。

MySQL中的典型替代方案,如果您需要“related_info”列表,则使用group_concat

select id, group_concat(related_info), count(*)
from my_table
where <complex filtering on related_info here>
group by id;

最后一种方法,假设related_info是唯一标识每一行的单个列:

select mt.id, mt.related_info, t.cnt
from my_table mt join
     (select id, group_concat(related_info) as relatedInfoList, count(*) as cnt
      from my_table
      where <complex filtering on related_info here>
      group by id
     ) t
     on mt.id = t.id and
        find_in_set(related_info, relatedInfoList) > 0

这会将“related_info”转换为列表,然后匹配回原始数据。这也可以使用原始数据中的唯一ID(id不基于样本数据)来完成。

答案 1 :(得分:0)

尝试使用Count分析功能。语法为COUNT(*)OVER(PARTITION BY ...)。你可以在这里找到更多: http://msdn.microsoft.com/en-us/library/ms189461.aspx