SQLRU.net
Разработка приложений баз данных

Начало » Использование СУБД » Firebird, HQbird, InterBase » Запрос на выборку строки с самой свежей датой
Запрос на выборку строки с самой свежей датой [сообщение #2967] Thu, 10 August 2023 12:26 Переход к следующему сообщению
SergDev в настоящее время не в онлайне  SergDev
Сообщений: 4
Зарегистрирован: March 2023
Junior Member
Нужна помощь в составлении запроса. Сам никак не разберусь.

Есть таблица с ценами на товар, нужно найти цену, которая актуальна на текущую дату. В таблице хранится порядковый номер записи, айди товара, цена, дата начала действия цены, дата окончания действия цены. Не всегда может быть дата окончания действия цены, но часто есть новая цена, которая начала действовать. Нужно выбрать именно ту цену, которая актуальна на момент выборки.
ID | GOODS_ID | PRICE | DATE_BEGIN | DATE_END
 1    100        50     01/01/2022   null
 2    100        65     01/02/2022   30/03/2022
 3    100        75     01/05/2022   null
 4    100       100     01/07/2022   null
самый простой вариант конечно же чтобы в неактуальных ценах DATE_END был не NULL
SELECT * FROM PRICES WHERE GOODS_ID = 100 AND DATE_END IS NULL
Re: Запрос на выборку строки с самой свежей датой [сообщение #2968 является ответом на сообщение #2967] Thu, 10 August 2023 12:31 Переход к предыдущему сообщениюПереход к следующему сообщению
МП в настоящее время не в онлайне  МП
Сообщений: 799
Зарегистрирован: August 2022
Географическое положение: бурятский тун...
Senior Member
у тебя задача не по FireBird.
Re: Запрос на выборку строки с самой свежей датой [сообщение #2969 является ответом на сообщение #2968] Thu, 10 August 2023 12:47 Переход к предыдущему сообщениюПереход к следующему сообщению
stelvic в настоящее время не в онлайне  stelvic
Сообщений: 8
Зарегистрирован: November 2022
Junior Member
select p.* from prices p left join prices p1 on p1.goods_id=p.goods_id and p1.date_begin>p.date_begin where p.date_end is null and p1.id is null.
Как-то так. Не проверял. С date_end могут быть проблемы
Re: Запрос на выборку строки с самой свежей датой [сообщение #2971 является ответом на сообщение #2969] Thu, 10 August 2023 14:29 Переход к предыдущему сообщениюПереход к следующему сообщению
МП в настоящее время не в онлайне  МП
Сообщений: 799
Зарегистрирован: August 2022
Географическое положение: бурятский тун...
Senior Member
или нам чего-то недоговаривают, или задача поставлена криво.
какого хрена в таблице присутствует поле DATE_END, если допускается существование нескольких НЕЗАКРЫТЫХ периодов с разными датами DATE_BEGIN!
Re: Запрос на выборку строки с самой свежей датой [сообщение #2972 является ответом на сообщение #2971] Thu, 10 August 2023 15:05 Переход к предыдущему сообщениюПереход к следующему сообщению
BlackEric в настоящее время в онлайне  BlackEric
Сообщений: 294
Зарегистрирован: June 2022
Senior Member
Акции так делаются. Скидка с... по...
Поэтому нельзя искать по последней дате просто.
Re: Запрос на выборку строки с самой свежей датой [сообщение #2973 является ответом на сообщение #2972] Thu, 10 August 2023 15:23 Переход к предыдущему сообщениюПереход к следующему сообщению
МП в настоящее время не в онлайне  МП
Сообщений: 799
Зарегистрирован: August 2022
Географическое положение: бурятский тун...
Senior Member
акция - отдельная сЦущность.
нефиг её пихать в прайсы.
Re: Запрос на выборку строки с самой свежей датой [сообщение #2974 является ответом на сообщение #2973] Thu, 10 August 2023 15:41 Переход к предыдущему сообщению
shavluk в настоящее время не в онлайне  shavluk
Сообщений: 67
Зарегистрирован: June 2022
Географическое положение: Одеса
Member
У меня подобная структура. Для себя я понял что наличие поля date_end - излишне, т.к. иногда могут изменить переоценку задним числом, ввести новую накладную и т.д. Иногда случались конфликты при одновременном смене цены.
Я решил следующей структурой

CREATE TABLE ITEM_PRICE_DOC (
    ID          INTEGER NOT NULL,
    ID_ITEM     INTEGER NOT NULL,
    ID_NPRICE   INTEGER NOT NULL,
    DATE_START  DATE,
    PRICE       NUMERIC(12,4),
    ID_DOC      INTEGER,
);

ALTER TABLE ITEM_PRICE_DOC ADD CONSTRAINT PK_ITEM_PRICE_DOC PRIMARY KEY (ID);

ALTER TABLE ITEM_PRICE_DOC ADD CONSTRAINT FK_ITEM_PRICE_DOC_1 FOREIGN KEY (ID_DOC) REFERENCES DOC (ID) ON DELETE CASCADE;
ALTER TABLE ITEM_PRICE_DOC ADD CONSTRAINT FK_ITEM_PRICE_DOC_2 FOREIGN KEY (ID_ITEM) REFERENCES ITEM (ID);

CREATE DESCENDING INDEX ITEM_PRICE_DOC_IDX2 ON ITEM_PRICE_DOC (ID_ITEM, ID_NPRICE, DATE_START, PRICE);
В моем случае
id_item - ID товара
id_nprice - ID группы цен
id_doc - ID документа, в котором сделана переоценка

Для получения цены на указанную дату есть такая процедура

create or alter procedure GET_ITEM_PRICE (
    ID_ITEM integer,
    ID_NPRICE integer,
    DATE_NK date = null)
returns (
    PRICE numeric(12,4),
    DATE_START date,
    ID_DOC integer,
    ID integer)
as
begin
  if (id_nprice <> 0) then
  begin
    select first 1 price, date_start, id_doc, id from item_price_doc
    where id_item = :id_item and id_nprice = :id_nprice and
          date_start <= coalesce(:date_nk, max_date())
    order by date_start desc, price desc
    into price, date_start, id_doc, id;
  end

  price = coalesce(price, 0);
  suspend;
end
Соответственно, для получения цены на требуемую дату, запрос будет что-то типа такого

select g.*, p.price
from items g
left join get_item_price(g.id, 1, '10.08.2023') p on 1=1
Предыдущая тема: Скорость выборки
Следующая тема: Помогите с выборкой
Переход к форуму:
  


Текущее время: Sat Apr 27 10:20:57 GMT+3 2024

Общее время, затраченное на создание страницы: 0.00619 секунд