powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Нужна помощь с запросом
18 сообщений из 18, страница 1 из 1
Нужна помощь с запросом
    #33884648
DenisLagoda
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть таблица PRICE с ценами на товары с историей их изменения, с полями :
datefrom -дата с которой вводится эта цена
price_cena - новая цена
tovar - код товара
magazin- код магазина

Цены на товар постоянно меняются с произвольной периодичностью. Мне надо получить прайс на любой день
...
Рейтинг: 0 / 0
Нужна помощь с запросом
    #33884717
Фотография pamir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот упрощенный пример, без магазина. Дальше сообразите сами. Проверял на оракле, поэтому может где-то что-то с синтаксисом. Тоже сообразите.

Код: plaintext
1.
2.
3.
4.
5.
CREATE TABLE tst_price (price NUMBER, tovar NUMBER, fd DATE)

SELECT tp.* FROM tst_price tp, 
  (SELECT tovar, MAX(fd) AS ldt FROM tst_price WHERE fd<now()
  GROUP BY tovar) srez
WHERE tp.tovar=srez.tovar AND tp.fd=srez.ldt
...
Рейтинг: 0 / 0
Нужна помощь с запросом
    #33884740
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вариант №1:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
select * 
  from price
 where datefrom = (
                     select max(datefrom)
                       from price p1
                      where p1.tovar = price.tovar
                        and p1.datefrom <= <твоя дата>
                  )


Вариант №2:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select price.* 
  from price
 inner join
       (
         select tovar,
                max(datefrom) max_date
           from price
          where datefrom <= <твоя дата>
          group by tovar
       ) p1 
    on price.datefrom = p1.max_date

Замени, где выделено, <твоя дата> на интересующую тебя дату и будет тебе счастье.

з.ы.
есть еще как минимум два варианта решения этой проблемы.
Но я тебе их не скажу - ибо один сильно накладный, а второй я уже показывал как-то в пределах этого форума

-----------------------------------------------------------------------------------------------------------------------------------------
З.Ы.
Неспешно ищу работу, согласен на переезд в Москву или Питер
...
Рейтинг: 0 / 0
Нужна помощь с запросом
    #33884763
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владимор КоневВариант №1:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
select * 
  from price
 where datefrom = (
                     select max(datefrom)
                       from price p1
                      where p1.tovar = price.tovar
                        and p1.datefrom <= <твоя дата>
                  )


Вариант №2:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select price.* 
  from price
 inner join
       (
         select tovar,
                max(datefrom) max_date
           from price
          where datefrom <= <твоя дата>
          group by tovar
       ) p1 
    on price.datefrom = p1.max_date

Замени, где выделено, <твоя дата> на интересующую тебя дату и будет тебе счастье.

з.ы.
есть еще как минимум два варианта решения этой проблемы.
Но я тебе их не скажу - ибо один сильно накладный, а второй я уже показывал как-то в пределах этого форума



-----------------------------------------------------------------------------------------------------------------------------------------
З.Ы.
Неспешно ищу работу, согласен на переезд в Москву или Питер

Во втором варианте небольшая неточность при копи/пасте закралась - потерялось условие соединения по коду товата:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
select price.* 
  from price
 inner join
       (
         select tovar,
                max(datefrom) max_date
           from price
          where datefrom <= <твоя дата>
          group by tovar
       ) p1 
    on price.datefrom = p1.max_date
   and price.tovar = p1.tovar
...
Рейтинг: 0 / 0
Нужна помощь с запросом
    #33884767
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pamirВот упрощенный пример, без магазина. Дальше сообразите сами. Проверял на оракле, поэтому может где-то что-то с синтаксисом. Тоже сообразите.

Код: plaintext
1.
2.
3.
4.
5.
CREATE TABLE tst_price (price NUMBER, tovar NUMBER, fd DATE)

SELECT tp.* FROM tst_price tp, 
  (SELECT tovar, MAX(fd) AS ldt FROM tst_price WHERE fd<now()
  GROUP BY tovar) srez
WHERE tp.tovar=srez.tovar AND tp.fd=srez.ldt
А можешь за один проход по таблице сделать это же???
;)
...
Рейтинг: 0 / 0
Нужна помощь с запросом
    #33884779
Фотография pamir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владимор Конев pamirВот упрощенный пример, без магазина. Дальше сообразите сами. Проверял на оракле, поэтому может где-то что-то с синтаксисом. Тоже сообразите.

Код: plaintext
1.
2.
3.
4.
5.
CREATE TABLE tst_price (price NUMBER, tovar NUMBER, fd DATE)

SELECT tp.* FROM tst_price tp, 
  (SELECT tovar, MAX(fd) AS ldt FROM tst_price WHERE fd<now()
  GROUP BY tovar) srez
WHERE tp.tovar=srez.tovar AND tp.fd=srez.ldt
А можешь за один проход по таблице сделать это же???
;)
В оракле надо копать в сторону аналитических функций. Вероятнее всего получилось бы (даже уверен, проверять лень). А в постгресе не знаю.
...
Рейтинг: 0 / 0
Нужна помощь с запросом
    #33884843
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pamirВ оракле надо копать в сторону аналитических функций. Вероятнее всего получилось бы (даже уверен, проверять лень). А в постгресе не знаю.Никаких аналитических функций. Только встроенный функционал, стандартные (для PostgreSQL) SQL-функции по работе с датой и строками + групповые функции

Кстати, аналитические функции тебе и в оракле не помогли бы, таки пришлось бы писать "обертку" - ведь в пределах одного запроса невозможно во фразе WHERE обращаться к результатам работы аналитической функции из секции SELECT этого же запроса.
Ибо аналитическая функция отрабатывает после WHERE, GROUP BY, HAVING.
То есть на момент выполнения WHERE результатов работы функции не существует.
...
Рейтинг: 0 / 0
Нужна помощь с запросом
    #33884851
Фотография pamir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владимор Конев pamirВ оракле надо копать в сторону аналитических функций. Вероятнее всего получилось бы (даже уверен, проверять лень). А в постгресе не знаю.Никаких аналитических функций. Только встроенный функционал, стандартные (для PostgreSQL) SQL-функции по работе с датой и строками + групповые функции

Кстати, аналитические функции тебе и в оракле не помогли бы, таки пришлось бы писать "обертку" - ведь в пределах одного запроса невозможно во фразе WHERE обращаться к результатам работы аналитической функции из секции SELECT этого же запроса.
Ибо аналитическая функция отрабатывает после WHERE, GROUP BY, HAVING.
То есть на момент выполнения WHERE результатов работы функции не существует.
Блин, вот я не очень силен в аналит. ф-циях. Поэтому всегда проверяю. Сейчас поленился и вляпался

Надо подумать.
...
Рейтинг: 0 / 0
Нужна помощь с запросом
    #33885553
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pamirНадо подумать.Чтобы легче думалось, вот тебе тынц
Справедливости ради нужно отметить, что сей подход я подглядел у Elic-а

Там если с синтаксисом MySQL не разберешься, то сразу даю подсказку - основная суть подхода в том, что нужно искать максимум / минимум строки, образованой конкатенацией поля с датой в формате yyyymmddhh24miss (время можно во внимание не брать, если цены не меняются по нескулько раз на день) с полем, которое необходимо вытащить на "заданную дату"

если в синтаксис PostgreSQL перевести не сможешь, то в понедельник дам верный ответ.
А сейчас я уже до дома собираюсь...
...
Рейтинг: 0 / 0
Нужна помощь с запросом
    #33885639
domanix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да- весьма красивое решение...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
create table price (id integer ,cena numeric( 18 , 2 ),datefrom date);
insert into price values ( 1 , 1 . 32 ,'01.01.2005');
insert into price values ( 1 , 2 . 45 ,'02.01.2005');
insert into price values ( 1 , 3 . 67 ,'03.01.2005');
insert into price values ( 2 , 1 . 56 ,'01.01.2005');
insert into price values ( 2 , 3 . 55 ,'03.01.2005');

select id,
  substr(  max(  to_char(datefrom,'YYYYMMDD')||cena  ),   9 )::numeric( 18 , 2 )
from price
    where datefrom<'03.01.2005'
group by id

...
Рейтинг: 0 / 0
Нужна помощь с запросом
    #33885705
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
select distinct on (id) id,cena,date from ... where date<? order by id,date desc
...
Рейтинг: 0 / 0
Нужна помощь с запросом
    #33885803
domanix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
О, а это решение еще краше и без извратов..
Снимаю шляпу...
...
Рейтинг: 0 / 0
Нужна помощь с запросом
    #33887988
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LeXa NalBatselect distinct on (id) id,cena,date from ... where date<? order by id,date desc
domanixО, а это решение еще краше и без извратов..
Снимаю шляпу...
А можно пояснить, что вернет сиё чудо на приведенном domanix-ом наборе данных?
Кроме того, если на каждый товар вытащится ровна одна строка с ценой на дату, максимально близкую с низу относитиельно заданной, то зачем тогда в запросе нужна сортировка по полю с датой???
...
Рейтинг: 0 / 0
Нужна помощь с запросом
    #33888270
domanix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SELECT DISTINCT ON (expression [, expression ...]) select_list ...
где выражение expression может быть вычисляемым полем с использованием столбцов результирующего набора.
Если однажды вычисленное значение повторяется вновь - то такая запись игнорируется и не выдается в результирующий набор.А выдается только первая запись.
Поэтому в нашем случае нужно сперва отсортировать результат по дате чтобы получить нужный результат.

DISTINCT ON (expr..) - фича принадлежащая только постгресу. И не безопасная..
...
Рейтинг: 0 / 0
Нужна помощь с запросом
    #33888273
domanix
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторAlternatively, an arbitrary expression can determine what rows are to be considered distinct:

SELECT DISTINCT ON (expression [, expression ...]) select_list ...
Here expression is an arbitrary value expression that is evaluated for all rows. A set of rows for which all the expressions are equal are considered duplicates, and only the first row of the set is kept in the output. Note that the “first row” of a set is unpredictable unless the query is sorted on enough columns to guarantee a unique ordering of the rows arriving at the DISTINCT filter. (DISTINCT ON processing occurs after ORDER BY sorting.)

The DISTINCT ON clause is not part of the SQL standard and is sometimes considered bad style because of the potentially indeterminate nature of its results. With judicious use of GROUP BY and subqueries in FROM the construct can be avoided, but it is often the most convenient alternative.
...
Рейтинг: 0 / 0
Нужна помощь с запросом
    #33888279
Фотография pamir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владимор Конев LeXa NalBatselect distinct on (id) id,cena,date from ... where date<? order by id,date desc
domanixО, а это решение еще краше и без извратов..
Снимаю шляпу...
А можно пояснить, что вернет сиё чудо на приведенном domanix-ом наборе данных?
Кроме того, если на каждый товар вытащится ровна одна строка с ценой на дату, максимально близкую с низу относитиельно заданной, то зачем тогда в запросе нужна сортировка по полю с датой???
Владимир, я проверил этот вариант на постгресе - как ни удивительно - работает. Надо почитать про distinct в постгресе - видимо он работает иначе, чем в оракле. Получается, что он выдает уникальные по id записи, беря первую (для этого и сортировка).
Ушел читать доку :о)

PS. А Ваш вариант меня поверг в шок - так просто, но догадаться до него не так уж легко :)
...
Рейтинг: 0 / 0
Нужна помощь с запросом
    #33888314
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
domanixDISTINCT ON (expr..) - фича принадлежащая только постгресу. И не безопасная..Я в доке порылся и сам до этого дошел, но всё равно спасибо за разъяснения.
В этом случае мой вариант более универсален, ибо его можно легко адаптировать практически под любую СУБД...
...
Рейтинг: 0 / 0
Нужна помощь с запросом
    #33888331
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pamirВладимир, я проверил этот вариант на постгресе - как ни удивительно - работает. Надо почитать про distinct в постгресе - видимо он работает иначе, чем в оракле. Получается, что он выдает уникальные по id записи, беря первую (для этого и сортировка).
Ушел читать доку :о)Нет, сам дистинкт работает как и везде - выдает уникальный набор данных из SELECT-LIST-а.
А такаое "специфическое поведение" ему "придает" постгресовская фича ON :)

pamirPS. А Ваш вариант меня поверг в шок - так просто, но догадаться до него не так уж легко :) А-га, есть такое дело (это про простоту решения).
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Нужна помощь с запросом
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]