[ОТВЕТИТЬ]
Опции темы
03.02.2010 02:24  
YuraZ
Привет.
Предлагаю, заинтересованным, разминку для ума. Подобного рода задачи на sql.ru называт "пятничными" :) Так или иначе, многие с подобного рода задачами салкиваются. Как правило, решение тоже, так или иначе работает :) Но хотелось бы, получить наиболее "красивое" решение, с применением именно "изюминок" Oracle. Сразу скажу, что у меня нет более-менее красивого решения этой задачи. Но хочется, с вашей помощью, его найти. И так, давайте попробуем.
Имеем таблицу вида:
Код:
ARTICLE   DATE         PRICE
000001    01.01.2006   100
000001    01.01.2007   200
000001    01.01.2008   300
000001    01.01.2009   400
000001    01.01.2010   500
000002    01.01.2006   100
000002    01.01.2007   200
000002    01.01.2008   150
000002    01.01.2009   220
000002    01.01.2010   210
Необходимо отобрать по каждоум артикулу ОДНИМ запросом последнюю цену. Не максимальную, а имено последнюю.
Для желающих попробовать, вот код:
Код:
CREATE TABLE YZTEST(
  ARTICLE  VARCHAR2(50) NOT NULL,
  ARTDATE  DATE NOT NULL,
  PRICE    NUMBER(14, 2))
/

INSERT INTO YZTEST(ARTICLE, ARTDATE, PRICE) VALUES('000001', TO_DATE('01.01.2006', 'DD.MM.YYYY'), 100);
INSERT INTO YZTEST(ARTICLE, ARTDATE, PRICE) VALUES('000001', TO_DATE('01.01.2007', 'DD.MM.YYYY'), 200);
INSERT INTO YZTEST(ARTICLE, ARTDATE, PRICE) VALUES('000001', TO_DATE('01.01.2008', 'DD.MM.YYYY'), 300);
INSERT INTO YZTEST(ARTICLE, ARTDATE, PRICE) VALUES('000001', TO_DATE('01.01.2009', 'DD.MM.YYYY'), 400);
INSERT INTO YZTEST(ARTICLE, ARTDATE, PRICE) VALUES('000001', TO_DATE('01.01.2010', 'DD.MM.YYYY'), 500);

INSERT INTO YZTEST(ARTICLE, ARTDATE, PRICE) VALUES('000002', TO_DATE('01.01.2006', 'DD.MM.YYYY'), 100);
INSERT INTO YZTEST(ARTICLE, ARTDATE, PRICE) VALUES('000002', TO_DATE('01.01.2007', 'DD.MM.YYYY'), 200);
INSERT INTO YZTEST(ARTICLE, ARTDATE, PRICE) VALUES('000002', TO_DATE('01.01.2008', 'DD.MM.YYYY'), 150);
INSERT INTO YZTEST(ARTICLE, ARTDATE, PRICE) VALUES('000002', TO_DATE('01.01.2009', 'DD.MM.YYYY'), 220);
INSERT INTO YZTEST(ARTICLE, ARTDATE, PRICE) VALUES('000002', TO_DATE('01.01.2010', 'DD.MM.YYYY'), 210);
Вбиваем его в тот же SQL Navigator (я пользовался именно им), и пробуем сделать выборку.
 
03.02.2010 08:59  
OlegON
Сделать процедурку и ею потом пользоваться, это "один запрос"? В противном случае решение "одним запросом" выливается в такие безумные сортировки, что никакого ТЕМПа не хватает при большом количестве артикулов. ИМХО.
Цель "одного запроса"?
 
03.02.2010 09:24  
twix
Цитата:
Сообщение от OlegON
Сделать процедурку и ею потом пользоваться, это "один запрос"? В противном случае решение "одним запросом" выливается в такие безумные сортировки, что никакого ТЕМПа не хватает при большом количестве артикулов. ИМХО.
Цель "одного запроса"?
тут важна не причина, а процесс и варианты решений.
пятничная задачка совсем не обязательно должна иметь практическую пользу (8
 
03.02.2010 09:27  
Requin
Один из вариантов применение псевдостолбца ROWNUM
Код:
SELECT *
    FROM
        (SELECT *
            FROM YZTEST
            WHERE ARTICLE = 'Требуемый_Артикул'
            ORDER BY ARTDATE DESC)
 WHERE
    ROWNUM < 2
 
03.02.2010 09:28  
Mtirt
Угу, только у тебя 2 запроса, один вложен в другой.
 
03.02.2010 09:46  
MirProd
Код:
select article, max(price) keep (dense_rank last order by artdate) lprice
from yztest
group by article
 
03.02.2010 11:03  
Requin
Еще один вариант есть.

Код:
SELECT DISTINCT article, FIRST_VALUE(price) OVER(PARTITION BY article ORDER BY artdate DESC) lprice
FROM yztest
 
03.02.2010 17:52  
YuraZ
Цитата:
Сообщение от MirProd
Код:
select article, max(price) keep (dense_rank last order by artdate) lprice
from yztest
group by article
Цитата:
Сообщение от Requin
Еще один вариант есть.

Код:
SELECT DISTINCT article, FIRST_VALUE(price) OVER(PARTITION BY article ORDER BY artdate DESC) lprice
FROM yztest
Лихо.
Протестировал на базе магазина работающего примерно год, ~10 касс, 22.000 карточек. Отбирал цену без налогов из приходных накладных. Запрос от MirProd отрабатывает за 2.8 с, запрос от Requin отрабатывает за 5с.
 
 
Опции темы


Часовой пояс GMT +3, время: 11:09.

Все в прочитанное - Календарь - RSS - - Карта - Вверх 👫 Яндекс.Метрика
Форум сделан на основе vBulletin®
Copyright ©2000 - 2016, Jelsoft Enterprises Ltd. Перевод: zCarot и OlegON
В случае заимствования информации гипертекстовая индексируемая ссылка на Форум обязательна.