Question : Returning First and Last Rows, grouped by columns.

Hi,

Scenario: Each user can enter multiple updates into a table, (maybe once a month, maybe a hundred times), throughout the course of the year. I want to return the GUID and COST for the first and last entries grouped by each user, month and year and then tag so we know which is which (for entry into a report to filter/group by):

i.e.
1:
2:
3:
4:
5:
6:
7:
USER         MONTH       YEAR    COST      GUID        ENTRYDATE                             TYPE 
------------------------------------------------------------------------------------------------
USER E      MAY            2010     22000    D490...      2010-05-21 11:59:55.000       FIRST 
USER E      MAY            2010     650        D223...      2010-05-31 23:00:00.000       LAST
USER E      JUNE           2010     23500    DCA0...     2010-06-15 13:30:18.000       FIRST 
USER E      JUNE           2010     1000      6C90...      2010-06-24 11:50:55.000       LAST


Obviously for User E I want the '2010-05-21 12:02:32.000' and '2010-06-16 07:13:06.000' dates removed.

Here is an example table containing the data I'm use for the above.

The problem I've found using MIN/MAX on EntryDate is that the GUID causes the grouping to fail. I'd put in an example of the queries I've been trying but to be honest, they all seem to be useless, so would be interested to know how someone else would come at the problem.

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
USERNAME	COST	GUID					ENTRYDATE 
USER A		1000	40879A8B-D964-DF11-8C38-001635810CA9	2010-05-21 13:05:36.000
USER A		2500	EA40279C-D964-DF11-8C38-001635810CA9	2010-05-21 13:06:04.000
USER B		6000	F62384AB-0A90-DF11-8C38-001635810CA9	2010-05-31 23:00:00.000
USER C		1975	AE2384AB-0A90-DF11-8C38-001635810CA9	2010-05-31 23:00:00.000
USER D		12000	542384AB-0A90-DF11-8C38-001635810CA9	2010-05-31 23:00:00.000
USER E		22000	D490B55E-D064-DF11-8C38-001635810CA9	2010-05-21 11:59:55.000
USER E		300	7EF4F8BB-D064-DF11-8C38-001635810CA9	2010-05-21 12:02:32.000
USER E		650	D22384AB-0A90-DF11-8C38-001635810CA9	2010-05-31 23:00:00.000
USER F		1270	8A2384AB-0A90-DF11-8C38-001635810CA9	2010-05-31 23:00:00.000
USER G		800	782384AB-0A90-DF11-8C38-001635810CA9	2010-05-31 23:00:00.000
USER H		6400	6F672602-8278-DF11-8C38-001635810CA9	2010-06-15 13:29:23.000
USER E		23500	DCA02523-8278-DF11-8C38-001635810CA9	2010-06-15 13:30:18.000
USER E		6620	26191E9C-1679-DF11-8C38-001635810CA9	2010-06-16 07:13:06.000
USER E		1000	6C905CBE-867F-DF11-8C38-001635810CA9	2010-06-24 11:50:55.000
USER H		1500	FDD2B4F8-8178-DF11-8C38-001635810CA9	2010-06-15 13:29:07.000
USER D		18750	490E50EE-8178-DF11-8C38-001635810CA9	2010-06-15 13:28:50.000
USER C		6640	CE53C31F-1579-DF11-8C38-001635810CA9	2010-06-16 07:02:28.000
USER C		6840	BE9526D4-7A84-DF11-8C38-001635810CA9	2010-06-30 19:08:13.000

Answer : Returning First and Last Rows, grouped by columns.

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
SELECT T.USERNAME, T.MONTH, T.YEAR, Yt.COST, Yt.GUID, Yt.ENTRYDATE, 'FIRST' [Type]
FROM (
	SELECT  USERNAME, 
			MONTH(ENTRYDATE) [MONTH], 
			YEAR(ENTRYDATE) [YEAR], 
			MIN(ENTRYDATE) MinDate
	FROM YourTable
	GROUP BY USERNAME, MONTH(ENTRYDATE), YEAR(ENTRYDATE) 
) T INNER JOIN YourTable Yt ON T.USERNAME = Yt.USERNAME AND T.MinDate = Yt.ENTRYDATE

UNION

SELECT T.USERNAME, T.MONTH, T.YEAR, Yt.COST, Yt.GUID, Yt.ENTRYDATE, 'LAST' [Type]
FROM (
	SELECT  USERNAME, 
			MONTH(ENTRYDATE) [MONTH], 
			YEAR(ENTRYDATE) [YEAR], 
			MAX(ENTRYDATE) MaxDate
	FROM YourTable
	GROUP BY USERNAME, MONTH(ENTRYDATE), YEAR(ENTRYDATE) 
) T INNER JOIN YourTable Yt ON T.USERNAME = Yt.USERNAME AND T.MaxDate = Yt.ENTRYDATE
Random Solutions  
 
programming4us programming4us