2014-02-03 2 views
0

У меня есть следующий (сгущенный) запрос для начала:Как выбрать правильную строку на основе даты вступления в силу?

WITH Product_List AS 
    (SELECT J.Product_ID, 
      N.Product_Name, 
      J.Unit_Price, 
      J.Effective_Date, 
      ROW_NUMBER() OVER (PARTITION BY J.Product_ID ORDER BY J.Effective_Date DESC) AS  RowNum 
    FROM Company.dbo.Pricing_File AS J 
    LEFT JOIN Company.dbo.No_pricing_File AS N ON J.Product_ID = N.Product_ID) 

Данные это тянет будет выглядеть как на это:

J.Product_ID | N. Product_Name | J.Unit_Price | J.Effective_Date | RowNum 
123456  | Product_1  | 12.34  | 01-04-14   | 1 
123456  | Product_1  | 12.56  | 01-04-13   | 2 
123456  | Product_1  | 12.80  | 01-04-12   | 3 
567898  | Product_2  | 10.00  | 01-01-14   | 1 
567898  | Product_2  | 9.50   | 01-01-13   | 2 

Я сейчас, используя этот список для извлечения данных из для столбец Product_Name и Unit_price, но для запроса необходимо вывести правильный unit_price на основе даты вступления в силу. Вот остальная часть моего запроса:

SELECT 
    A.*, 
    B.*, 
    Product_List_1.Product_Name, 
    Product_List_1.Unit_Price, 
FROM 
    Company.dbo.Company_Master AS A 
LEFT JOIN Company.dbo.Product_Info AS B ON A.Claim_Number = B.Claim_Number AND A.Customer_Number = B.Customer_Number 
LEFT JOIN Product_List AS Product_List_1 ON B.Product_ID_1 = Product_List_1.Product_ID AND 
B.Fill_Date >= Product_List_1.Effective_Date AND 
Product_List_1.RowNum = 1 

Это работает точно так, как ожидалось, за исключением одного случая. Когда J.Effective_Date - это что-то вроде 01-04-14, а B.Fill_Date - это что-то вроде 12-30-13, критерии, с которыми я соединяюсь, больше не верны. Либо дата вступления в силу не> = Fill Дата ИЛИ RowNum = 1. Я попытался изменить последнюю строку из JOIN ON от:

Product_List_1.RowNum = 1 

в

Product_List_1.RowNum LIKE '[1-2]' 

и другие варианты, но затем он вернет более одного результата, а не только того, что ему нужно.

Мой вопрос: как я могу получить этот запрос, чтобы выбрать правильную запись из таблицы Product_List на основе Fill_Date и Effective_Date?

Спасибо за любую помощь. Дайте мне знать, если у вас есть какие-либо вопросы или вы нуждаетесь в разъяснении.

+0

Ваша дата хранится в виде строки символов? –

+0

Нет, как Fill_Date, так и Effective_Date хранятся в виде типа данных даты и времени. – user3006876

+0

Не могли бы вы построить [SQL Fiddle] (http://sqlfiddle.com/#!3) с достаточным количеством данных для демонстрации случаев краев, которые нарушают ваш запрос, и ожидаемых результатов ... примеры данных и желаемые результаты часто намного эффективнее при поиске нужного вам запроса, а не в попытке отменить разработку запроса, основанного на неправильных результатах, которые он производит. –

ответ

1

Если появляется, вы пытаетесь получить ценообразование, применимое к продукту для данного требования или заказа, основанного на перечне цен с датой вступления в силу. В этом случае способ, которым я это делал в прошлом, заключается в том, чтобы объединить ваши цены вместе, чтобы вы получили дату начала и окончания вместо эффективной даты и присоединились к дате начала и окончания.

Вот пример:

;WITH Product_List AS 
(SELECT J.Product_ID, 
      N.Product_Name, 
      J.Unit_Price, 
      J.Effective_Date, 
      ROW_NUMBER() OVER (PARTITION BY J.Product_ID ORDER BY J.Effective_Date DESC) AS  RowNum 
    FROM Company.dbo.Pricing_File AS J 
    LEFT JOIN Company.dbo.No_pricing_File AS N ON J.Product_ID = N.Product_ID 
) 
, ctePriceRange as 
(
    SELECT 
     l1.Product_ID, 
     l1.Product_Name, 
     l1.Unit_Price, 
     l1.Effective_Date as PriceStart, 
     l2.Effective_Date as PriceEnd 
    FROM Product_List l1 
    LEFT JOIN Product_List l2 
    ON l1.Product_ID = l2.Product_ID 
    and l1.RowNum = l2.RowNum - 1 --Join this price up with the next available price to get the end date 
) 
SELECT 
    A.*, 
    B.*, 
    Product_List_1.Product_Name, 
    Product_List_1.Unit_Price, 
FROM 
    Company.dbo.Company_Master AS A 
LEFT JOIN Company.dbo.Product_Info AS B ON A.Claim_Number = B.Claim_Number AND A.Customer_Number = B.Customer_Number 
LEFT JOIN ctePriceRange AS Product_List_1 ON B.Product_ID_1 = Product_List_1.Product_ID AND 
B.Fill_Date >= Product_List_1.PriceStart AND 
(
    B.Fill_Date < Product_List_1.PriceEnd 
    OR 
    Product_List_1.PriceEnd is null --this handles the last effective price that is listed, which will not have an end date 
) 
+0

Это именно то, что мне нужно. Спасибо! Я, конечно, буду помнить об этом в будущем. – user3006876

Смежные вопросы