0

我在使用以下查询时遇到了困难。我一直在尝试优化它,也许让它更具可读性。假设我有 3 个表 orders_returned、orders_completed、orders_delivered 以及匹配列 oder_id、customer_id。根据选择的选项,我可能需要检索已交付、然后返回并最终完成的订单(所有三个表中出现相同的 order_id),这些订单具有相同的 customer_id。此外,我可能只需要检索已交付和退回的订单,在这种情况下,我会AND order_id IN (SELECT order_id FROM ORDERS_COMPLETED)WHERE子句中省略。例如,获取客户 John 和 Tim 交付和退回的订单 到目前为止,我的查询如下所示:

SELECT order_id
FROM
(
    SELECT order_id, customer_id
    FROM ORDERS_RETURNED
    UNION
    SELECT order_id, customer_id
    FROM ORDERS_COMPLETED
    UNION
    SELECT order_id, customer_id
    FROM ORDERS_DELIVERED
)
WHERE 
    customer_id IN ('customer1', 'customer2', ...)
    AND order_id IN (SELECT order_id FROM ORDERS_RETURNED)
    AND order_id IN (SELECT order_id FROM ORDERS_COMPLETED)
    AND order_id IN (SELECT order_id FROM ORDERS_DELIVERED)

我还在学习 SQL,想看看是否有更好的选择。

编辑:我正在使用 Oracle 数据库。还有一个 Orders 表,它有不同的 order_ids 和一些其他不相关的列。它不存储 customer_ids。此外,订单可能出现在一个表中,也可能只出现在其中两个表中,所以我认为连接在这里没有用。

4

3 回答 3

2

由于您有一个 Order 表,我假设您也将 CustomerId 存储在该表中。假设是这样,试试这个:

SELECT DISTINCT O.OrderId
FROM Orders O
   LEFT JOIN Orders_Completed OC ON O.OrderId = OC.OrderId
   LEFT JOIN Orders_Delivered OD ON O.OrderId = OD.OrderId
   LEFT JOIN Orders_Returned ORE ON O.OrderId = ORE.OrderId
WHERE O.CustomerId IN (...)
   AND OD.OrderId IS NOT NULL AND ORE.OrderId IS NOT NULL AND OC.OrderId IS NULL

此特定查询将返回所有不同的订单,其中客户在 (...) 中的订单已交付和退回,但尚未完成。切换使用 IS NULL 和 IS NOT NULL 以获得所需的输出。

祝你好运。

于 2013-02-03T08:34:42.740 回答
0

您应该使用联接而不是内部/嵌套查询。

请尝试以下方法::

SELECT A.order_id, A.customer_id FROM ORDERS_RETURNED A 
INNER JOIN ORDERS_COMPLETED B ON A.order_id = B.order_id AND A.customer_id = B.customer_id
INNER JOIN ORDERS_DELIVERED C ON A.order_id = C.order_id AND A.customer_id = C.customer_id
Where A.customer_id IN ('customer1', 'customer2', ...)
于 2013-02-03T08:22:34.087 回答
0

你可以这样做:

with data
     as (select customer_id,
                order_id,
                nvl(max(case status when 'RETURNED' then 'Y' end), 'N') returned,
                nvl(max(case status when 'COMPLETED' then 'Y' end), 'N') completed,
                nvl(max(case status when 'DELIVERED' then 'Y' end), 'N') delivered
           from (select 'RETURNED' status, order_id, customer_id
                   from orders_returned
                 union all
                 select 'COMPLETED' status, order_id, customer_id
                   from orders_completed
                 union all
                 select 'DELIVERED' status, order_id, customer_id
                   from orders_delivered)
          group by customer_id, order_id)
select *
  from data
 where returned = 'Y'
   and delivered = 'Y'
   and customer_id in ('xx', 'xxx') ;

或者

with data
     as (select customer_id,
                order_id,
                max(returned) returned,
                max(completed) completed,
                max(delivered) delivered
           from (select 'Y' returned, null completed, null delivered, order_id, customer_id
                   from orders_returned
                 union all
                 select null, 'Y', null, order_id, customer_id
                   from orders_completed
                 union all
                 select null, null, 'Y', order_id, customer_id
                   from orders_delivered)
          group by customer_id, order_id)
select *

从返回的数据 = 'Y' 和交付 = 'Y' 和 customer_id in ('xx', 'xxx');

例如:http ://sqlfiddle.com/#!4/3e2fb/2

于 2013-02-03T14:12:54.330 回答