Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
Page47
Master Smack Fu Yak Hacker
2878 Posts |
Posted - 2007-08-24 : 08:39:09
|
DDL:create table #test( a int, d1 datetime, d2 datetime) Sample Data:insert into #testselect 1, '20070101', '20070301'union allselect 1, '20070501', '20070901'union allselect 2, '20070101', '20070601'union allselect 2, '20070301', '20070801' Expected Result:a d1 d2-------------------------------------1 20070101 200703011 20070501 200709012 20070101 20070801 There are two situations in the data. I want all rows where for each {a} the dates {d1,d2} do not overlap. When dates overlap for a given {a}, I want the data grouped by {a} with the aggregates min(d1), max(d2) applied against the dates.Thanks for your help ...Jayto here knows when |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-08-24 : 09:07:54
|
This is better suited for you--Stage the data;WITH yak (a, start, stop, grp)as ( select t.a, t.d1, t.d2, 0 from ( SELECT a, d1, d2, row_number() over (partition by a order by d1) as recid from #test ) as t where recid = 1 union all select a, d1, case when stop < d1 and stop >= d2 then stop when stop < d1 and stop < d2 then d2 else d2 end, case when stop < d1 then grp +1 else grp end from ( SELECT y.stop, t.a, t.d1, t.d2, y.grp, row_number() over (partition by t.a order by t.d1) as recid from #test as t inner join yak as y on y.a = t.a and y.start < t.d1 ) as t where recid = 1)-- Show the expected outputselect a, min(start) as start, max(stop) as stop from yakgroup by a, grporder by a, 2 E 12°55'05.25"N 56°04'39.16" |
 |
|
|
Page47
Master Smack Fu Yak Hacker
2878 Posts |
Posted - 2007-08-24 : 09:22:14
|
quote: Specifies a temporary named result set, known as a common table expression (CTE). This is derived from a simple query and defined within the execution scope of a single SELECT, INSERT, UPDATE, or DELETE statement. This clause can also be used in a CREATE VIEW statement as part of its defining SELECT statement.-BOL
I've never been able to figure out/find the syntax for creating a CTE within a view ...Jayto here knows whennevermind |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-08-24 : 09:26:56
|
[code]create table test( a int, d1 datetime, d2 datetime)goinsert into testselect 1, '20070101', '20070301'union allselect 1, '20070501', '20070901'union allselect 2, '20070101', '20070601'union allselect 2, '20070301', '20070801'gocreate view vwtestas--Stage the dataWITH yak (a, start, stop, grp)as ( select t.a, t.d1, t.d2, 0 from ( SELECT a, d1, d2, row_number() over (partition by a order by d1) as recid from test ) as t where recid = 1 union all select a, d1, case when stop < d1 and stop >= d2 then stop when stop < d1 and stop < d2 then d2 else d2 end, case when stop < d1 then grp +1 else grp end from ( SELECT y.stop, t.a, t.d1, t.d2, y.grp, row_number() over (partition by t.a order by t.d1) as recid from test as t inner join yak as y on y.a = t.a and y.start < t.d1 ) as t where recid = 1)-- Show the expected outputselect top (100) percent a, min(start) as start, max(stop) as stop from yakgroup by a, grporder by a, 2goselect * from vwtest [/code] E 12°55'05.25"N 56°04'39.16" |
 |
|
|
Page47
Master Smack Fu Yak Hacker
2878 Posts |
Posted - 2007-08-24 : 12:57:38
|
| Thanks, man ... awesome.Jayto here knows when |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-08-25 : 18:03:38
|
UPDATE:This works on SQL Server 2005, but not in SQL Server 2008!Windowed aggregates and sequence functions are not allowed in the recursive part of recursive common table expression 'yak'.When changing compatibility mode to 90 on SQL Server 2008 the qúery above works.For a working algorithm for both 2005 and 2008 with highest compatibility mode, see http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=88422 E 12°55'05.25"N 56°04'39.16" |
 |
|
|
|
|
|
|
|