我有三个表,客户,订单和客户订单,如下所示:
Customers:
ID NAME
1 Peter
2 Jack
3 Lisa
Orders:
ID INIT_DATE END_DATE
1 10-11-2014 10-11-2015
2 23-11-2014 01-01-2015
3 23-11-2014 03-05-2015
4 04-04-2016 08-11-2016
5 13-07-2016 01-11-2016
6 04-06-2016 30-10-2016
7 12-11-2014 01-05-2015
8 26-11-2014 10-10-2015
9 05-09-2016 11-11-2016
Customers_Orders:
CUSTOMER_ID ORDER_ID
1 1
1 2
1 3
2 4
2 5
2 6
3 7
3 8
3 9
我需要让所有订单都过时的客户。我的意思是,那些sysdate的命令在init_date和end_date之间不。在这种情况下,预期的结果是1-Peter。
我试过的是这个:
SELECT *
FROM Customers
WHERE
ID NOT IN (
SELECT DISTINCT Customers_Orders.CUSTOMER_ID
FROM Customers_Orders, Orders
WHERE Customers_Orders.ORDER_ID = Orders.ID
AND Orders.INIT_DATE <= SYSDATE AND Orders.END_DATE > SYSDATE
)
但我不喜欢“NOT IN”语法因为性能低下。还有另一种方式吗?
注意:日期格式为dd-mm-yyyy
编辑:我更正了问题(粗体)。
答案 0 :(得分:2)
加入三个表并使用条件聚合来检查客户的所有订单是否都已过时。
select c.id,c.name
from customer_orders co
join orders o on o.id=co.order_id
join customers c on c.id=co.customer_id
group by c.id,c.name
having count(case when sysdate between co.init_date and co.end_date then 1 end) = 0
答案 1 :(得分:2)
这将排除INIT_DATE少于今天且END_DATE&gt;的所有客户。今天。
with Curr_ord as
(
select co1.customer_id, co1.order_id
from customers_orders co1
inner join orders o1
on o1.id = co1.order_id
where o1.INIT_DATE <= sysdate
and o1.END_DATE > sysdate
)
select C1.*
from Customers C1
left join Curr_Ord CO2
on C1.Customer_ID = CO2.Customer_ID
where CO2.Customer_ID is null
答案 2 :(得分:-1)
为什么不加入?
SELECT DISTINCT C.CUSTOMER_ID
FROM customers c
JOIN Customers_Orders co on co.customer_id = c.customer_id
JOIN Orders od on od.order_id = co.order_id
WHERE Od.INIT_DATE <= SYSDATE
AND Od.END_DATE > SYSDATE
通过对订单进行正确的索引,您可以通过将过滤器放入连接来获得性能提升:
SELECT DISTINCT C.CUSTOMER_ID
FROM customers c
JOIN Customers_Orders co on co.customer_id = c.customer_id
JOIN (SELECT od.order_id
from Orders
WHERE Od.INIT_DATE <= SYSDATE
AND Od.END_DATE > SYSDATE ) od on od.order_id = co.order_id
但现在我们正在讨论性能调整策略....在这种情况下,我们需要讨论您的数据配置文件等以获得最佳解决方案。