Как выбрать значение в таблице на основе диапазона дат, который может измениться - PullRequest
3 голосов
/ 24 марта 2019

Кажется, я не могу найти вопрос, который конкретно отвечает требованиям того, что я пытаюсь сделать здесь, но извиняюсь, если это не так.

У меня есть пример таблицы:

    type|start_date|end_date  |cost|

    bananas|2019-01-01|2019-01-31|100
    bananas|2019-02-01|2019-02-28|95
    juice  |null      |null      |55

И так далее.Суть таблицы в том, что «еда» или что-то еще может быть другой ценой, основанной на другом временном диапазоне, однако есть некоторые предметы, например, сок, на которые не влияют изменения даты (т.е. они остаются постоянными).).

В другой таблице я хочу найти значение на основе диапазона дат в таблице выше.

Например:

customerId|transaction_date|item   |quantity|

abc123    |2019-01-25      |bananas|4
abc126    |2019-02-06      |bananas|4
abc128    |2019-02-09      |juice  |1

Итак, первые дваклиенты покупали бананы, но один в январе и один в феврале.Тогда другой клиент купил сок.Как я могу вернуть правильную соответствующую стоимость, основываясь на моей другой таблице.

Я пытался сделать, где дата BETWEEN два, но это отталкивает любые другие даты, которые не существуют в таблице цен.Я также пытался использовать CASE, чтобы подойти к этому, но безрезультатно.

Каков наилучший подход к этому?

Я ожидаю, что результат приведет к объединенной таблицесо следующим:

customerId|transaction_date|item   |quantity|cost|

abc123    |2019-01-25      |bananas|4       |100
abc126    |2019-02-06      |bananas|4       |95
abc128    |2019-02-09      |juice  |1       |55

Где к столбцу cost присоединяются вышеуказанные критерии?

Ответы [ 3 ]

2 голосов
/ 24 марта 2019

Вы можете использовать ISNULL в левом соединении.

SELECT P.*, C.cost
FROM Purchases P 
LEFT JOIN Product_Costs C ON P.item = C.type 
      AND P.transaction_date >= ISNULL(C.start_date, P.transaction_date) 
      AND P.transaction_date <= ISNULL(C.end_date, P.transaction_date);

Модифицированная скрипка Ника: http://sqlfiddle.com/#!18/e366b/6

1 голос
/ 24 марта 2019

Вы можете использовать внешнее приложение:

  SELECT p.*,
  c.cost
  FROM Purchases AS p
      OUTER APPLY (
          SELECT TOP 1 c.cost
              FROM Product_Costs AS c
              WHERE p.transaction_date BETWEEN c.start_date AND c.end_date
                  AND c.type = p.Item
      ) AS c;

Я создал скрипку Sql, используя данные вашего примера: http://sqlfiddle.com/#!18/e366b/2/0

1 голос
/ 24 марта 2019

Вы можете использовать коррелированный подзапрос:

select t2.*,
       (select t1.cost
        from table1 t1
        where t1.type = t2.type and
              t2.transaction_date >= t1.start_date and
              t2.transaction_date <= t1.end_date 
       ) as cost
from table2 t2;

Или вы можете использовать left join:

select t2.*, t1.cost
from table2 t2 left join
     table1 t1
     on t1.type = t2.type and
        t2.transaction_date >= t1.start_date and
        t2.transaction_date <= t1.end_date ;

EDIT:

Вы можете обрабатывать NULL значений с помощью OR:

select t2.*, t1.cost
from table2 t2 left join
     table1 t1
     on t1.type = t2.type and
        (t2.transaction_date >= t1.start_date or
         t1.start_date is null
        ) and
        (t2.transaction_date <= t1.end_date or
         t1.end_date is null
        );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...