2015-09-27 230 views
1

我只是学习SQL专门的聚合函数和子查询SQL计数聚合函数和子查询

我有列c0, c1, c2, c3数据库表。

我的查询:

SELECT ID, count(ID) 
FROM ((select ID from tbl1 where c0 BETWEEN 4 and 7) 
UNION ALL 
(select ID from tbl1 where c1 BETWEEN 5 and 7) 
UNION ALL 
(select ID from tbl1 where c2 BETWEEN 6 and 10) 
UNION ALL 
(select ID from tbl1 where c3 BETWEEN 1 and 5)) AS tbl 
GROUP BY ID HAVING count(ID) >= 2 

可以在上面重写,结果查询会更快?或者如何让我的查询更快?

+1

你真的有4个不同的列,你正在测试?当一行满足多个条件(或者是查询的目的)时会发生什么? –

+0

多数民众赞成的目的,数出现.. – mich

回答

1

我不认为你需要聚合。只需计算每一行中的匹配。

假设id是表中唯一的:

select id, 
     ((c0 between 4 and 7) + (c1 between 5 and 7) + (c2 between 6 and 10) + 
     (c3 between 1 and 5) 
     ) as cnt 
from tbl1 
having cnt >= 2; 

MySQL的对待布尔在数值上下文为数字,以1为真,0代表假,所以表达式c0 between 4 and 7基本上等同于case when c0 between 4 and 7 then 1 else 0 end,但更容易写。

MySQL还扩展having子句,因此它可以在没有group by的情况下工作。在这种情况下,它的行为如同where,但您可以使用select中定义的别名。

注意:如果列的值为NULL,则稍微复杂一点。

如果id不是唯一的,那么你基本上可以做同样的事情与聚集:

select id, 
     sum((c0 between 4 and 7) + (c1 between 5 and 7) + (c2 between 6 and 10) + 
      (c3 between 1 and 5) 
     ) as cnt 
from tbl1 
group by id 
having cnt >= 2; 

然而,一列名为id应该是唯一的。

+0

谢谢..我可以使用上述查询索引? – mich

+0

@mich。 。 。您不能在查询中使用索引。为了使用索引,您需要在原始查询中采用该方法。然而,我怀疑全表扫描比合并来自四个索引的结果要快,除非每个条件都非常非常严格(比如小于1%的行)。 –