Страница 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
папа Карло
badreyka писал(а):неее... ну явно не хватает в МС СКЛ Сервере LEAD() and LAG() функций
)

https://connect.microsoft.com/SQLServer ... kID=254388
http://rafael-salas.blogspot.com/2008/0 ... tions.html

какие-бы варианты не предлагали - все равно будет ходить 2 раза по таблице или по индексу так как left join не избежать
так что придется смирится
не понятно почему с WITH ходит два раза... и вообще да, оракловых функций в этом месте не хватает. :(

Re: Умным от сиквела... :)

Добавлено: 22 июл 2009, 11:21
badreyka
Explain plan в студию, plz

Re: Умным от сиквела... :)

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