Sql Oracle:如何在列中仅获取具有特定条件的行
我有三张桌子,顾客,订单和顾客订单如下:Sql Oracle:如何在列中仅获取具有特定条件的行,sql,oracle,Sql,Oracle,我有三张桌子,顾客,订单和顾客订单如下: 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
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
)
但是我不喜欢非语法的,因为它的性能很低。还有别的办法吗
注:日期格式为dd-mm-yyyy
编辑:我用粗体更正了这个问题。连接三个表,并使用条件聚合检查客户的所有订单是否都过期
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
连接这三个表,并使用条件聚合检查客户的所有订单是否已过期
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
为什么不直接加入呢
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
但现在我们讨论的是性能调整策略。。。。在这种情况下,我们需要讨论您的数据配置文件等,以获得最佳解决方案。为什么不直接加入
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
但现在我们讨论的是性能调整策略。。。。在这种情况下,我们需要讨论您的数据配置文件等,以获得最佳解决方案。这将排除初始日期小于今天且结束日期>今天的所有客户
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
这将排除初始日期小于今天且结束日期>今天的所有客户
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
peter的订单是如何过时的?他的所有订单都在2015年结束,sysdate不在起始日期和结束日期之间`您的数据模型允许多个客户下订单,这可能不是您想要的。我会在表格订单上放置一个客户ID。请看我更正了这个问题,谢谢@LamakHow peter的订单是否过时了?,他的所有订单都在2015年结束,sysdate不在起始日期和结束日期之间。您的数据模型允许多个客户下订单,这可能不是您想要的。我会在订单上放置一个客户ID。请看,我更正了这个问题,谢谢@Lamakb,因为这只会返回有订单的客户。我需要所有订单都过期的客户。因为这只返回有订单正在进行的客户。我需要所有订单都过期的客户。