Author |
Topic |
R
Constraint Violating Yak Guru
328 Posts |
Posted - 2012-07-24 : 07:04:37
|
The following statement creates a result set from a table variable:SELECT CAST(YEAR(t.dateCreated) as nvarchar) + '-' + CAST(RIGHT('0' + RTRIM(MONTH(t.dateCreated)), 2) as nvarchar) as colName, -- needs to be 'YYYY-MM' so that ASP.NET can sort as a string COUNT(*) AS totalsFROM @tbl_results tGROUP BY DATENAME(MONTH, t.dateCreated) + ' ' + CAST(YEAR(t.dateCreated) AS nvarchar), MONTH(t.dateCreated), YEAR(t.dateCreated)ORDER BY 1 This produces the following results:colName totals--------------2010-08 12010-10 952010-11 5522011-01 1532011-02 278 Can anyone advise how to enhance the query to produce a cumulative total alongside the current totals column? I saw this done using OVER but can't figure it out. It needs to work in SQL 2005 please.Thanks! |
|
madhivanan
Premature Yak Congratulator
22864 Posts |
Posted - 2012-07-24 : 07:13:38
|
Is this?SELECT convert(char(7),t.dateCreated,120) as colName, -- needs to be 'YYYY-MM' so that ASP.NET can sort as a string COUNT(*) AS totals, sum(1) over () as aggregateFROM @tbl_results tGROUP BY convert(char(7),t.dateCreated,120)ORDER BY 1 MadhivananFailing to plan is Planning to fail |
|
|
R
Constraint Violating Yak Guru
328 Posts |
Posted - 2012-07-24 : 07:18:01
|
HiThanks but it doesn't work I'm afraid. I get this resultset:colName totals aggregate2010-08 1 222010-10 95 222010-11 552 222011-01 153 222011-02 278 222011-03 4 222011-04 6 22 |
|
|
madhivanan
Premature Yak Congratulator
22864 Posts |
Posted - 2012-07-24 : 07:24:12
|
What is wrong with it and what is your expected result?MadhivananFailing to plan is Planning to fail |
|
|
R
Constraint Violating Yak Guru
328 Posts |
Posted - 2012-07-24 : 07:44:46
|
I need to increase the totals column for each row if possible, e.g.colName totals aggregate2010-08 1 12010-10 95 962010-11 552 6482011-01 153 8012011-02 278 1079 |
|
|
sunitabeck
Master Smack Fu Yak Hacker
5155 Posts |
Posted - 2012-07-24 : 07:53:25
|
I think Madhivanan has been spending too much time working with SQL 2012 which has enhanced windowing functions The following is not a very efficient approach, but this should work. I also have sort of recast your method of generating the YYYY-MM string to fit this.;WITH cte AS( SELECT DATEADD(mm,DATEDIFF(mm,0,dateCreated),0) AS Created, COUNT(*) AS totals FROM tbl_results GROUP BY DATEADD(mm,DATEDIFF(mm,0,dateCreated),0))SELECT CONVERT(CHAR(7),a.Created,120) AS colName, a.totals, b.CumulativeTotalFROM cte a CROSS APPLY ( SELECT SUM(totals) AS CumulativeTotal FROM cte c WHERE c.Created <= a.Created ) b; |
|
|
R
Constraint Violating Yak Guru
328 Posts |
Posted - 2012-07-24 : 08:18:42
|
Hi sunitabeckThat does work thank you, but I have concerns about your statement regarding it not being very efficient. Is there an efficient way in SQL 2005?? |
|
|
sunitabeck
Master Smack Fu Yak Hacker
5155 Posts |
Posted - 2012-07-24 : 08:24:21
|
quote: Originally posted by R Hi sunitabeckThat does work thank you, but I have concerns about your statement regarding it not being very efficient. Is there an efficient way in SQL 2005??
Most of the usual approaches for calculating running totals in SQL (before SQL 2012) are pretty inefficient. The unusual approach, which I am not a great proponent of, is the quirky update method. You can read all about it and see some examples at Jeff Moden's article here: http://www.sqlservercentral.com/articles/T-SQL/68467/ |
|
|
R
Constraint Violating Yak Guru
328 Posts |
Posted - 2012-07-24 : 08:31:05
|
Okay thanks for that. Currently the pricing of SQL 2012 puts it way higher than the cheque-signers are prepared to pay, so it's 2005 for now!I've been playing around with your method. Although I've never used CROSS APPLY, I modified your version and achieved this, which seems to work okay:;WITH cte AS ( SELECT CAST(YEAR(t.dateCreated) as nvarchar) + '-' + CAST(RIGHT('0' + RTRIM(MONTH(t.dateCreated)), 2) as nvarchar) as colName, COUNT(*) AS totals FROM @tbl_results t GROUP BY DATENAME(MONTH, t.dateCreated) + ' ' + CAST(YEAR(t.dateCreated) AS nvarchar), MONTH(t.dateCreated), YEAR(t.dateCreated) )SELECT *FROM cte c1 CROSS APPLY ( SELECT SUM(totals) as ct FROM cte c2 WHERE c2.colName <= c1.colName ) bORDER BY c1.colName Do any issues stand out here with regards to efficiency that make it any better/worse than your method? |
|
|
sunitabeck
Master Smack Fu Yak Hacker
5155 Posts |
Posted - 2012-07-24 : 08:43:44
|
The change I made to the way the YYYY-MM was calculated was to avoid comparing strings to determine the date range. In this case that should work correctly whether you use my approach, or the way you were converting dates to a string and then comparing. However, as general practice experts recommend that we avoid doing that. i.e., when you want to compare dates, do that using data types of datetime, date etc. |
|
|
madhivanan
Premature Yak Congratulator
22864 Posts |
Posted - 2012-07-24 : 08:46:44
|
<<I think Madhivanan has been spending too much time working with SQL 2012 which has enhanced windowing functions >>Yes MadhivananFailing to plan is Planning to fail |
|
|
|