我有一张注册表,大约有300K记录。我需要一个SQL语句来显示该特定日期的注册总数吗?
select
count('x'),CONVERT(varchar(12),date_created,111)
from reg group by
cONVERT(varchar(12),date_created,111)
order by
CONVERT(varchar(12),date_created,111)
此查询的结果:
169 2011/03/24
3016 2011/03/25
2999 2011/03/26
期望的结果:
2011/03/25 3016+169
2011/03/26 2999+3016+169
如何做到这一点?
答案 0 :(得分:2)
只需使用SUM
即可获得累积计数:
SELECT reg1.date_created,
SUM(reg2.val) AS CumulativeValue
FROM (
select count(*) as RegCountForDay,
date_created
from reg
group by date_created
) AS reg1
LEFT JOIN reg AS reg2 ON (reg2.date_created <= reg1.date_created)
GROUP BY reg1.date_created
答案 1 :(得分:2)
目前您有两个选择:第一个是使用vbence建议的连接,第二个是子查询:
SELECT r1.date_created, (SELECT COUNT(*) FROM reg r2
WHERE r2.date_created<=r1.date_created) AS total_num
FROM reg r1;
这两种方法产生类似的执行计划。
将来,当SQLServer使用聚合函数为ORDER BY
实现OVER
时,您将能够编写
SELECT date_created,
COUNT(*) OVER(ORDER BY date_created) as total_num
FROM reg;
答案 2 :(得分:2)
这是两个版本。我已经在一台速度非常慢的计算机上测试了超过6000天的100000行,内存不足,这表明cte版本比循环版本更快。这里建议的其他版本(到目前为止)要慢得多,前提是我已正确理解了问题。
递归CTE (10秒)
-- Table variable to hold count for each day
declare @DateCount table(d int, c int, rn int)
insert into @DateCount
select
datediff(d, 0, date_created) as d,
count(*) as c,
row_number() over(order by datediff(d, 0, date_created)) as rn
from reg
group by datediff(d, 0, date_created)
-- Recursive cte using @DateCount to calculate the running sum
;with DateSum as
(
select
d, c, rn
from @DateCount
where rn = 1
union all
select
dc.d, ds.c+dc.c as c, dc.rn
from DateSum as ds
inner join @DateCount as dc
on ds.rn+1 = dc.rn
)
select
dateadd(d, d, 0) as date_created,
c as total_num
from DateSum
option (maxrecursion 0)
循环(14秒)
-- Table variable to hold count for each day
declare @DateCount table(d int, c int, rn int, cr int)
insert into @DateCount
select
datediff(d, 0, date_created) as d,
count(*) as c,
row_number() over(order by datediff(d, 0, date_created)) as rn,
0
from reg
group by datediff(d, 0, date_created)
declare @rn int = 1
-- Update cr with running sum
update dc set
cr = dc.c
from @DateCount as dc
where rn = @rn
while @@rowcount = 1
begin
set @rn = @rn + 1
update dc set
cr = dc.c + (select cr from @DateCount where rn = @rn - 1)
from @DateCount as dc
where rn = @rn
end
-- Get the result
select
dateadd(d, d, 0) as date_created,
cr as total_num
from @DateCount
编辑1真正快速的版本
-- Table variable to hold count for each day
declare @DateCount table(d int primary key, c int, cr int)
insert into @DateCount
select
datediff(d, 0, date_created) as d,
count(*) as c,
0
from reg
group by datediff(d, 0, date_created)
declare @rt int = 0
declare @anchor int
update @DateCount set
@rt = cr = @rt + c,
@anchor = d
option (maxdop 1)
-- Get the result
select
dateadd(d, d, 0) as date_created,
cr as total_num
from @DateCount
order by d
答案 3 :(得分:1)
试试这个。
SELECT r1.date_created,
COUNT(*) AS number
FROM (SELECT distinct(date_created) FROM reg) AS r1
LEFT JOIN reg AS r2 ON (r2.date_created <= r1.date_created)
GROUP BY r1.date_created
当然,您必须使用以下内容对表进行索引:
CREATE INDEX datefilter ON reg (date_created);
答案 4 :(得分:1)
你可以通过下面的sql查询来解决这个问题。你给了两列col1=Number
和col2=Date
Select DATE,OUTPUT=SUM(InnerValue) from
(
Select T1.Date, T1.Number, InnerValue=ISNULL(T2.Number,0) from
(
Select ID=DENSE_RANK() OVER(ORDER BY DATE),Date,Number from YourTable
) As T1
LEFT JOIN
(
Select ID=DENSE_RANK() OVER(ORDER BY DATE),Date,Number from YourTable
) AS T2
ON T1.ID >= T2.ID
) As MainTable GROUP BY DATE
答案 5 :(得分:0)
另一种选择是使用CLR定义您自己的运行总和函数,如以下链接中所述:
http://pavelpawlowski.wordpress.com/2010/09/30/sql-server-and-fastest-running-totals-using-clr/