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

Все, что вы хотели знать о программизме, но боялись спросить.
Ответить
Аватара пользователя
папа Карло
Шарманщик
Сообщения: 8565
Зарегистрирован: 17 фев 2003, 15:04
Откуда: НН -> BC -> WA -> UT -> CA

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

Сообщение папа Карло »

Как сделать наиболее оптимальным способом 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 также делает два сорта и скана... не понятно почему... есть солюшен чтобы хотябы сортило разок? это не одноразовая задача... иначе бы не спрашивал.

ну есть головы? :)
badreyka
Частый Гость
Сообщения: 46
Зарегистрирован: 21 июл 2007, 22:34
Откуда: Burnaby

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

Сообщение 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 |
--------------------------------------------------------------------
Аватара пользователя
папа Карло
Шарманщик
Сообщения: 8565
Зарегистрирован: 17 фев 2003, 15:04
Откуда: НН -> BC -> WA -> UT -> CA

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

Сообщение папа Карло »

идея таже... выглядит синтаксисом покороче и сканит вроде раз всего. я могу это "красиво" через WITH написать, но план к сожалению тот же самый и это сакс. :(
badreyka
Частый Гость
Сообщения: 46
Зарегистрирован: 21 июл 2007, 22:34
Откуда: Burnaby

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

Сообщение badreyka »

папа Карло писал(а):.. выглядит синтаксисом покороче
да уж... )
а в МС СКЛ Сервере нет похожей функции?
папа Карло писал(а): делал через WITH....
покажи, если не лень...
папа Карло писал(а): ... не понятно почему...
в твоем примере left join на самого себе... не поэтому ли 2 раза ходит? не знаю как там с МС СКЛ Сервер, но оракл сходил бы 2 раза
в моем примере все делается за один проход - был бы индекс сходил бы по нему...
Yuri Dimant
Пользователь
Сообщения: 107
Зарегистрирован: 02 авг 2004, 22:00

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

Сообщение 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
Аватара пользователя
папа Карло
Шарманщик
Сообщения: 8565
Зарегистрирован: 17 фев 2003, 15:04
Откуда: НН -> BC -> WA -> UT -> CA

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

Сообщение папа Карло »

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
даты от балды... реально там с милисекундами и абсолютно не равномерно... моет быть несколько секунд, могут бытьг годы.
Yuri Dimant
Пользователь
Сообщения: 107
Зарегистрирован: 02 авг 2004, 22:00

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

Сообщение Yuri Dimant »

Так выложите не от балды, неохото INSERTть
Аватара пользователя
Vovka
Завсегдатай
Сообщения: 250
Зарегистрирован: 18 фев 2003, 12:17

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

Сообщение Vovka »

чиса от балды. у тебя там не групы? мож типа група по филд1 и 2 а типа 3-й мин(3) и 4-й типа мах(3) ?
badreyka
Частый Гость
Сообщения: 46
Зарегистрирован: 21 июл 2007, 22:34
Откуда: Burnaby

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

Сообщение badreyka »

неее... ну явно не хватает в МС СКЛ Сервере LEAD() and LAG() функций
)

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

какие-бы варианты не предлагали - все равно будет ходить 2 раза по таблице или по индексу так как left join не избежать
так что придется смирится
Аватара пользователя
папа Карло
Шарманщик
Сообщения: 8565
Зарегистрирован: 17 фев 2003, 15:04
Откуда: НН -> BC -> WA -> UT -> CA

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

Сообщение папа Карло »

badreyka писал(а):неее... ну явно не хватает в МС СКЛ Сервере LEAD() and LAG() функций
)

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

какие-бы варианты не предлагали - все равно будет ходить 2 раза по таблице или по индексу так как left join не избежать
так что придется смирится
не понятно почему с WITH ходит два раза... и вообще да, оракловых функций в этом месте не хватает. :(
badreyka
Частый Гость
Сообщения: 46
Зарегистрирован: 21 июл 2007, 22:34
Откуда: Burnaby

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

Сообщение badreyka »

Explain plan в студию, plz
Аватара пользователя
папа Карло
Шарманщик
Сообщения: 8565
Зарегистрирован: 17 фев 2003, 15:04
Откуда: НН -> BC -> WA -> UT -> CA

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

Сообщение папа Карло »

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