| Начало » Использование СУБД » Firebird, HQbird, InterBase » Запрос на выборку строки с самой свежей датой Переход к форуму:
	| 
		
			| Запрос на выборку строки с самой свежей датой [сообщение #2967] | Thu, 10 August 2023 12:26  |  
			| 
				
				
					|  SergDev Сообщений: 4
 Зарегистрирован: March 2023
 | Junior Member |  |  |  
	| Нужна помощь в составлении запроса. Сам никак не разберусь. 
 Есть таблица с ценами на товар, нужно найти цену, которая актуальна на текущую дату. В таблице хранится порядковый номер записи, айди товара, цена, дата начала действия цены, дата окончания действия цены. Не всегда может быть дата окончания действия цены, но часто есть новая цена, которая начала действовать. Нужно выбрать именно ту цену, которая актуальна на момент выборки.
 
 самый простой вариант конечно же чтобы в неактуальных ценах DATE_END был не NULL
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
 
SELECT * FROM PRICES WHERE GOODS_ID = 100 AND DATE_END IS NULL
 |  
	|  |  |  
	|  |  
	|  |  
	|  |  
	|  |  
	|  |  
	| 
		
			| Re: Запрос на выборку строки с самой свежей датой [сообщение #2974 является ответом на сообщение #2973] | Thu, 10 August 2023 15:41  |  
			| 
				
				
					|  shavluk Сообщений: 88
 Зарегистрирован: 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
 
 |  
	|  |  | 
 
 
 Текущее время: Fri Oct 31 18:24:36 GMT+3 2025 
 Общее время, затраченное на создание страницы: 0.01349 секунд |