我正在尝试编写一个查询来根据多个不同的范围计算记录数。
我使用union
取得了成功,但我觉得有更好的方法。
以下是我所做的:
select count(col1) as range1
from tbl1
where col1 <= 15000
union
select count(col1) as range2
from tbl1
where col1 > 15001 and col1 <= 30000
union
select count(col1) as range3
from tbl1
where col1 > 30001 and col1 <= 45000
etc...
我正在使用sql server 2008.就像我上面所述,我很肯定有更好的方法来做到这一点,可能是这样的:sql count,
编辑:是的,数据库是sql 2008,下面的答案完全按照需要工作。我忘了提到我实际上正在通过coldfusion JSON
阅读serialized
文件serializeJSON
。所以在数据库中,下面的所有内容都运行良好,但查询的coldfusion查询不支持CASE
语句,或者它似乎不支持。
答案 0 :(得分:10)
一种方法是使用条件求和(对于单独列中的值):
select sum(case when col1 <= 15000 then 1 else 0 end) as range1,
sum(case when col1 > 15001 and col1 <= 30000 then 1 else 0 end) as range2,
sum(case when col1 > 30001 and col1 <= 45000 then 1 else 0 end) as range3
from tbl1;
另一种方法是使用group by
(对于不同行上的值):
select (case when col1 <= 15000 then 'range1'
when col1 > 15001 and col1 <= 30000 then 'range2'
when col1 > 30001 and col1 <= 45000 then 'range3'
else 'other'
end) as range, count(*) as cnt
from tbl1
group by (case when col1 <= 15000 then 'range1'
when col1 > 15001 and col1 <= 30000 then 'range2'
when col1 > 30001 and col1 <= 45000 then 'range3'
else 'other'
end);
我经常在这个表单中使用子查询:
select range, count(*)
from (select t.*,
(case when col1 <= 15000 then 'range1'
when col1 > 15001 and col1 <= 30000 then 'range2'
when col1 > 30001 and col1 <= 45000 then 'range3'
else 'other'
end) as range
from tbl1
group by range;
这样,range
的定义只出现一次。
编辑:
以上都使用了OP的逻辑。但是,上述逻辑错过了15001
和30001
的值。我的猜测是OP对于条件确实意味着col1 > 15000 and col1 <= 30000
和col1 > 30000 and col1 <= 45000
。但是,我没有改变它们,因为上面是原始问题的措辞(也许15001
和30001
有一些特别之处。
答案 1 :(得分:3)
怎么样;
select
count(case when col1 < 15000 then 1 else null end),
count(case when col1 > 15001 and col1 <= 30000 then 1 else null end),
count(case when col1 > 30001 and col1 <= 45000 then 1 else null end),
...
from tbl
答案 2 :(得分:1)
作为联盟中的第一个查询,您的列将全部称为“range1”。
select count(col1) as range1
from tbl1
where
col1 <= 15000
or
(col1 > 15001 and col1 <= 30000)
or
(col1 > 30001 and col1 <= 45000)
如果你想要单独的列,你会更喜欢这样的
SELECT sum(CASE WHEN col1 <= 15000 THEN 1 ELSE 0) range1,
sum(CASE WHEN (col1 > 15001 and col1 <= 30000) THEN 1 ELSE 0) range2,
sum(CASE WHEN (col1 > 30001 and col1 <= 45000) THEN 1 ELSE 0) range3
from tbl1
答案 3 :(得分:1)
就个人而言,我更喜欢使用派生(或物理)表来存储我的范围边界,然后我将其连接回来以查找我的结果。
我认为代码更简单,更容易扩展(如果需要)
有点像这样:
; WITH ranges (lbound, ubound) AS (
SELECT 0, 1500
UNION ALL SELECT 1500, 3000
UNION ALL SELECT 3000, 4500
)
SELECT ranges.lbound
, ranges.ubound
, Count(your_table.value) As turtle
FROM ranges
LEFT
JOIN your_table
ON your_table.value >= ranges.lbound
AND your_table.value < ranges.ubound
GROUP
BY ranges.lbound
, ranges.ubound
答案 4 :(得分:0)
这样的事情怎么样?我知道它适用于&lt; 15000而不是&lt; = 15000,但如果你说的是货币金额,那么&lt; = 15000和&gt; 15001错过了这些价值之间的任何东西。如果值非常大,您可以谈论编写大量范围。这样也可以轻松添加其他分组。
select cast([amount] as bigint) / 15000 * 15000, count(*)
from [transactions]
group by cast([amount] as bigint) / 15000
order by cast([amount] as bigint) / 15000