Начало » Использование СУБД » Firebird, HQbird, InterBase » Запрос на выборку строки с самой свежей датой 
	
		
		
			| Запрос на выборку строки с самой свежей датой [сообщение #2967] | 
			Thu, 10 August 2023 12:26   | 
		 
		
			
				
				
				
					
						  
						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: Запрос на выборку строки с самой свежей датой [сообщение #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 
		
		
		
 |  
	| 
		
	 | 
 
 
 |   
Переход к форуму:
 
 Текущее время: Tue Nov 04 03:56:41 GMT+3 2025 
 Общее время, затраченное на создание страницы: 0.00862 секунд 
 |