我似乎找不到一个专门解决我在这里想要做的事情的问题,但是如果不是这种情况,我深表歉意。
我有一个示例表:
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
列放在何处?
答案 0 :(得分:2)
您可以在左侧联接上使用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);
修改了Nick的小提琴:http://sqlfiddle.com/#!18/e366b/6
答案 1 :(得分:1)
您可以使用相关子查询:
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 ;
编辑:
您可以使用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
);
答案 2 :(得分:1)
您可以使用外部申请:
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 Fiddle:http://sqlfiddle.com/#!18/e366b/2/0