I have a table of registrations, around 300K records. I need a SQL statement that will show the total number of registrations for that particular day?
select
count('x'),CONVERT(varc开发者_StackOverflowhar(12),date_created,111)
from reg group by
cONVERT(varchar(12),date_created,111)
order by
CONVERT(varchar(12),date_created,111)
Result of this query:
169 2011/03/24
3016 2011/03/25
2999 2011/03/26
Desired outcome:
2011/03/25 3016+169
2011/03/26 2999+3016+169
How can this be done?
Here is two versions to do this. I have tested with 100000 rows spread over 6000 days on a really slow computer with not enough memory, and that shows that the cte version is faster than the loop version. The other versions suggested here (so far) is a lot slower, provided that I have understood the problem correctly.
Recursive CTE (10 seconds)
-- 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)
Loop (14 seconds)
-- 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
Edit 1 The really fast version
The quirky update
-- 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
Currently you have 2 options: first is using join as proposed by vbence, second is subquery :
SELECT r1.date_created, (SELECT COUNT(*) FROM reg r2
WHERE r2.date_created<=r1.date_created) AS total_num
FROM reg r1;
These 2 approaches generate similar execution plans.
In the future, when SQLServer implements ORDER BY
for OVER
with aggregate functions, you will be able to write
SELECT date_created,
COUNT(*) OVER(ORDER BY date_created) as total_num
FROM reg;
Simply use a SUM
to get a cumulative count:
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
Try this one.
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
Of course you have to index your table with something like:
CREATE INDEX datefilter ON reg (date_created);
you can solve this problem through below sql query..You have given two columns col1=Number
and 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
Another option is to use CLR to define your own Running Sum Function as described in the followig link:
http://pavelpawlowski.wordpress.com/2010/09/30/sql-server-and-fastest-running-totals-using-clr/
精彩评论