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.

 All Forums
 SQL Server 2005 Forums
 Transact-SQL (2005)
 Need help with a query

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 #test
select 1, '20070101', '20070301'
union all
select 1, '20070501', '20070901'
union all
select 2, '20070101', '20070601'
union all
select 2, '20070301', '20070801'


Expected Result:

a d1 d2
-------------------------------------
1 20070101 20070301
1 20070501 20070901
2 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 ...

Jay
to here knows when

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2007-08-24 : 08:45:11
I posted this yesterday. It may help you
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=88345



E 12°55'05.25"
N 56°04'39.16"
Go to Top of Page

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 output
select a,
min(start) as start,
max(stop) as stop
from yak
group by a,
grp
order by a,
2


E 12°55'05.25"
N 56°04'39.16"
Go to Top of Page

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 ...

Jay
to here knows when

nevermind
Go to Top of Page

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)
go

insert into test
select 1, '20070101', '20070301'
union all
select 1, '20070501', '20070901'
union all
select 2, '20070101', '20070601'
union all
select 2, '20070301', '20070801'
go


create view vwtest
as

--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 output
select top (100) percent a,
min(start) as start,
max(stop) as stop
from yak
group by a,
grp
order by a,
2
go

select * from vwtest [/code]


E 12°55'05.25"
N 56°04'39.16"
Go to Top of Page

Page47
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2007-08-24 : 12:57:38
Thanks, man ... awesome.

Jay
to here knows when
Go to Top of Page

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"
Go to Top of Page
   

- Advertisement -