"Hugo Kornelis" wrote:
> On Wed, 31 Oct 2007 21:44:21 -0700, SteveH wrote:
>
> >I have inherited a system that has a table with 9.7 million rows which grows
> >by around 5,000 a day. (SQL 2005)
> >
> >A record is written for each episode every time the unit/ward/doctor changes
> >as well as at 07:00, 15:00, 22:00 and 00:00 each day (changes in shift)
> >
> >Here is a sample
> >
> >episode unit ward doctor start_datetime end_datetime
> >X A B E 2007-10-01 00:00 2007-10-01 07:00
> >X A B E 2007-10-01 07:00 2007-10-01 15:00
> >X A B E 2007-10-01 15:00 2007-10-01 18:30
> >X A C E 2007-10-01 18:30 2007-10-01 22:00
> >X A C E 2007-10-01 22:00 2007-10-02 00:00
> >X A C E 2007-10-02 00:00 2007-10-02 07:00
> >X A C E 2007-10-02 07:00 2007-10-02 11:00
> >X A D E 2007-10-02 11:00 2007-10-02 15:00
> >X A D E 2007-10-02 15:00 2007-10-02 17:00
> >X A C E 2007-10-02 17:00 2007-10-02 18:45
> >
> >
> >I want to consolidate this information as episode/unit/ward/doctor level
> >
> >episode unit ward doctor start_datetime end_datetime
> >X A B E 2007-10-01 00:00 2007-10-01 18:30
> >X A C E 2007-10-01 18:30 2007-10-02 11:00
> >X A D E 2007-10-02 11:00 2007-10-02 17:00
> >X A C E 2007-10-02 17:00 2007-10-02 18:45
> >
> >I can do this using a cursor but was hoping that someone could suggest a
> >better solution.
> >
> >Be warned that as in the sample above, a patient can go from ward C to D
> >then back to C, so any thoughts of a simple min/max date grouped by
> >episode/ward/unit/doctor is out of the question.
> >
> >I have played with CTE's but don't really know what I am doing.
> >
> >Any help or greatly appreciated.
>
> Hi Steve,
>
> If you are running SQL Server 2005, you might be able to do this
> efficiently by using the new ranking functions, in a trick stolen from
> Itzik Ben-Gan:
>
> WITH TheCTE AS
> (SELECT episode, unit, ward, doctor, start_datetime, end_datetiime,
> ROW_NUMBER() OVER (PARTITION BY episode
> ORDER BY start_datetime) AS rn1,
> ROW_NUMBER() OVER (PARTITION BY episode, unit, ward, doctor
> ORDER BY start_datetime) AS rn2
> FROM YourTable)
> SELECT episode, unit, ward, doctor,
> MIN(start_datetime) AS start_datetime,
> MAX(end_datetime) AS end_datetime
> FROM TheCTE
> GROUP BY episode, unit, ward, doctor, rn1-rn2;
>
> (Untested - see
www.aspfaq.com/5006 if you prefer a tested reply)
>
> --
> Hugo Kornelis, SQL Server MVP
> My SQL Server blog:
http://sqlblog.com/blogs/hugo_kornelis