Solved

SQL 2005 Group By Month Select Last Value for Month

Posted on 2008-10-30
7
2,942 Views
Last Modified: 2012-06-21
I'm using the "Group By" to group by month. The values I am selecting are 'high', 'low' and 'close'. When I group, I want the highest 'high' (MAX), the lowest low (MIN), and the last close (date wise) in the month. Obviously I have the 'high' and 'low' figured out, MAX() and MIN() respectively, but I'm completely baffled by the 'close' value as there is no LAST() aggregate function. Any help would be appreciated; I've spent too many hours on it already, with no solution coming to me.

SELECT convert(datetime, cast(month(A1.Date) as varchar) + '/01/' + cast(year(A1.Date) as varchar), 101) as date,

MAX(high) AS high, MIN(low) AS low, ???? AS close 

FROM ( a nice big select ) 

WHERE date >= #startdate# and date<=#enddate#

GROUP BY YEAR(date), MONTH(date) ORDER BY date

Open in new window

0
Comment
Question by:Trinig
  • 4
  • 2
7 Comments
 
LVL 39

Expert Comment

by:appari
ID: 22847042

try this, the logic is get the last date of the month and if it is same as date value of current record select it otherwise assign null and then get Max out of the all values.

SELECT convert(datetime, cast(month(A1.Date) as varchar) + '/01/' + cast(year(A1.Date) as varchar), 101) as date,
MAX(high) AS high, MIN(low) AS low,
Max(case when
dateadd(m,1,date)- day(date) = date then close else null end)
AS close
FROM ( a nice big select )
WHERE date >= #startdate# and date<=#enddate#
GROUP BY YEAR(date), MONTH(date) ORDER BY date
0
 

Author Comment

by:Trinig
ID: 22847127
I'm not at work atm, so I can't try the solution, but I'm not sure this will work.  With our data, we don't have values for weekends and holidays, so there might not be data for the last day of a month.  If such is the case, I use the 2nd last day, or the 3rd last day, etc until there is data present.
0
 
LVL 39

Accepted Solution

by:
appari earned 500 total points
ID: 22847212
in that case you may try something like this using CTE

;
with nice_Select as (a nice big select )
SELECT convert(datetime, cast(month(A1.Date) as varchar) + '/01/' + cast(year(A1.Date) as varchar), 101) as date,
MAX(high) AS high, MIN(low) AS low,
Max(case when EOM is not null then close else null end)
AS close
FROM nice_Select Left Outer join (Select YEAR(date), MONTH(date), Max(date) EOM from nice_Select Group by YEAR(date), MONTH(date) ) as EOMDate
on date = EOM
WHERE date >= #startdate# and date<=#enddate#
GROUP BY YEAR(date), MONTH(date) ORDER BY date



0
Complete Microsoft Windows PC® & Mac Backup

Backup and recovery solutions to protect all your PCs & Mac– on-premises or in remote locations. Acronis backs up entire PC or Mac with patented reliable disk imaging technology and you will be able to restore workstations to a new, dissimilar hardware in minutes.

 
LVL 14

Expert Comment

by:rob_farley
ID: 22847787
I'm not sure why you can't use MAX(date), as if some dates are missing, the MAX could easily be the 29th of the month, or whatever.

But if you want more information again, I'd recommend using row_number().

You can easily provide a row number for each row, telling it to start again from one for each month. Something like:


select *, row_number() over (partition by year(date), month(date) order by date desc) as rn_backwards
from sometable

No need group by for this - that's what your partition is doing. Now you can select the rows where rn_backwards = 1, to get the final record for the month. Or you can "order by date asc" to get the first row of the month. This is an easy way to get a LAST or FIRST function out of SQL Server 2005.

select * from
(
select *, row_number() over (partition by year(date), month(date) order by date desc) as rn_backwards
from sometable
) t
where rn_backwards = 1; --Gives you the last row for each partition.

Hope this helps,

Rob

-- http://www.lobsterpot.com.au, http://msmvps.com/blogs/robfarley
0
 

Author Comment

by:Trinig
ID: 22849242
Rob,

I understand your method of getting the last date of the month, but I need to use that to get to related close value, which your method would do.  However, I also need the Max(high) and Min(low) which is why I was using the GROUP BY.  Is there a way to incorporate max(high) and min(low) into your row_number partition method?

I appreciate the comments, leaving for work soon so I'll be able to play with some suggestions.

-Ken
0
 

Author Closing Comment

by:Trinig
ID: 31511866
Thanks, the CTE worked great.  Never even thought to look at them.  All I have to do now is construct a weekly version.  Thanks again.
0
 

Author Comment

by:Trinig
ID: 22849975
appari's solution did the trick.  I had never even thought of trying CTE, as they still a bit new to me.  I appreciate the comments and help.
0

Featured Post

Backup Your Microsoft Windows Server®

Backup all your Microsoft Windows Server – on-premises, in remote locations, in private and hybrid clouds. Your entire Windows Server will be backed up in one easy step with patented, block-level disk imaging. We achieve RTOs (recovery time objectives) as low as 15 seconds.

Join & Write a Comment

Suggested Solutions

Nowadays, some of developer are too much worried about data. Who is using data, who is updating it etc. etc. Because, data is more costlier in term of money and information. So security of data is focusing concern in days. Lets' understand the Au…
This article explains how to reset the password of the sa account on a Microsoft SQL Server.  The steps in this article work in SQL 2005, 2008, 2008 R2, 2012, 2014 and 2016.
Using examples as well as descriptions, and references to Books Online, show the different Recovery Models available in SQL Server and explain, as well as show how full, differential and transaction log backups are performed
Viewers will learn how to use the INSERT statement to insert data into their tables. It will also introduce the NULL statement, to show them what happens when no value is giving for any given column.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now