Страница 1 из 1
Умным от сиквела... :)
Добавлено: 21 июл 2009, 14:56
папа Карло
Как сделать наиболее оптимальным способом type-II дименшен из примерно вот такого (МС СКЛ Сервер скажем 2008):
RowId | ID | Date
1 1 2007
2 1 2008
3 1 2009
4 2 2001
5 1 2010
охота получить такого типа:
RowId | ID | FromDate | ToDate
1 1 2007 2008
2 1 2008 2009
3 1 2009 2010
5 1 2010 NULL
4 2 2001 NULL
можно сделать через ранкинг функции... есть чтото проще что меньше ресурсов пожрет? след квери делает два тейбл скана и сорта...
Код: Выделить всё
select
s.rowid,
s.id,
s.archivedtim,
s.archivedtim as start_time,
d.archivedtim as end_time
from
(select *, rank() over (partition by id order by rowid) as sa_rankid from test with (nolock)) s
left join (select *, rank() over (partition by id order by rowid) as sa_rankid from test with (nolock)) d on d.id = s.id and d.sa_rankid = s.sa_rankid + 1
делал через WITH также делает два сорта и скана... не понятно почему... есть солюшен чтобы хотябы сортило разок? это не одноразовая задача... иначе бы не спрашивал.
ну есть головы?

Re: Умным от сиквела... :)
Добавлено: 21 июл 2009, 16:56
badreyka
сорри папа,
но у меня нет
(МС СКЛ Сервер скажем 2008)
тоka Oracle
но может чем-нибудь поможет
)
Код: Выделить всё
create table test_papa (rowid_ number, id number, sdate number)
/
analyze table test_papa compute statistics
/
select * from test_papa
/
ROWID_ ID SDATE
---------- ---------- ----------
1 1 2007
2 1 2008
3 1 2009
4 2 2001
5 1 2010
Код: Выделить всё
select
rowid_
,id
,sdate from_
,lead(sdate, 1, null) over (partition by id order by sdate asc nulls last) to_
from test_papa
/
ROWID_ ID FROM_ TO_
---------- ---------- ---------- ----------
1 1 2007 2008
2 1 2008 2009
3 1 2009 2010
5 1 2010
4 2 2001
Elapsed: 00:00:00.04
Код: Выделить всё
Explain plan
--------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost |
--------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5 | 35 | 5 |
| 1 | WINDOW SORT | | 5 | 35 | 5 |
| 2 | TABLE ACCESS FULL | TEST_PAPA | 5 | 35 | 2 |
--------------------------------------------------------------------
Re: Умным от сиквела... :)
Добавлено: 21 июл 2009, 17:23
папа Карло
идея таже... выглядит синтаксисом покороче и сканит вроде раз всего. я могу это "красиво" через WITH написать, но план к сожалению тот же самый и это сакс.

Re: Умным от сиквела... :)
Добавлено: 21 июл 2009, 20:40
badreyka
папа Карло писал(а):.. выглядит синтаксисом покороче
да уж... )
а в МС СКЛ Сервере нет похожей функции?
папа Карло писал(а):
делал через WITH....
покажи, если не лень...
папа Карло писал(а):
... не понятно почему...
в твоем примере left join на самого себе... не поэтому ли 2 раза ходит? не знаю как там с МС СКЛ Сервер, но оракл сходил бы 2 раза
в моем примере все делается за один проход - был бы индекс сходил бы по нему...
Re: Умным от сиквела... :)
Добавлено: 21 июл 2009, 23:23
Yuri Dimant
Based on posted DDL
create table #t (rowid int,id int, y int)
insert into #t values (1,1,2007)
insert into #t values (2,1,2008)
insert into #t values (3,1,2009)
insert into #t values (4,2,2001)
insert into #t values (5,1,2010)
select * from #t
left join #t t1
on t1.id=#t.id and t1.y =#t.y+1
order by #t.id
Re: Умным от сиквела... :)
Добавлено: 22 июл 2009, 00:23
папа Карло
Yuri Dimant писал(а):Based on posted DDL
create table #t (rowid int,id int, y int)
insert into #t values (1,1,2007)
insert into #t values (2,1,2008)
insert into #t values (3,1,2009)
insert into #t values (4,2,2001)
insert into #t values (5,1,2010)
select * from #t
left join #t t1
on t1.id=#t.id and t1.y =#t.y+1
order by #t.id
даты от балды... реально там с милисекундами и абсолютно не равномерно... моет быть несколько секунд, могут бытьг годы.
Re: Умным от сиквела... :)
Добавлено: 22 июл 2009, 01:07
Yuri Dimant
Так выложите не от балды, неохото INSERTть
Re: Умным от сиквела... :)
Добавлено: 22 июл 2009, 05:19
Vovka
чиса от балды. у тебя там не групы? мож типа група по филд1 и 2 а типа 3-й мин(3) и 4-й типа мах(3) ?
Re: Умным от сиквела... :)
Добавлено: 22 июл 2009, 07:01
badreyka
неее... ну явно не хватает в МС СКЛ Сервере LEAD() and LAG() функций
)
https://connect.microsoft.com/SQLServer ... kID=254388
http://rafael-salas.blogspot.com/2008/0 ... tions.html
какие-бы варианты не предлагали - все равно будет ходить 2 раза по таблице или по индексу так как left join не избежать
так что придется смирится
Re: Умным от сиквела... :)
Добавлено: 22 июл 2009, 10:51
папа Карло
не понятно почему с WITH ходит два раза... и вообще да, оракловых функций в этом месте не хватает.

Re: Умным от сиквела... :)
Добавлено: 22 июл 2009, 11:21
badreyka
Explain plan в студию, plz
Re: Умным от сиквела... :)
Добавлено: 22 июл 2009, 12:24
папа Карло
badreyka писал(а):Explain plan в студию, plz
запрограммил я все через тот квери что в самом начале написал... квери с WITH надо снова писать.... релиз очередной у меня на этой неделе, чуть выдохну отпишу.