2

我有两张桌子,OrderOrderItem。存在一对多关系Order.Order_ID=OrderItem.Order_ID

我想要一个查询返回一个列表,显示每个订单的状态,完成或未完成。

COMPLETE Order 定义为所有相关 OrderItem 记录NULL在字段中都有一个非空值的订单OrderItem.Delivery_ID

这是我到目前为止所拥有的:

  SELECT Order.Order_ID, 'INCOMPLETE' AS Order_status
  FROM Order 
  WHERE EXISTS
    (SELECT *
     FROM OrderItem 
     WHERE OrderItem.Order_ID=Order.Order_ID 
     AND (OrderItem.Delivery_ID IS NULL OR OrderItem.Delivery_ID=''))
UNION 
  SELECT Order.Order_ID, 'COMPLETE' AS Order_status
  FROM Order 
  WHERE NOT EXISTS
    (SELECT *
     FROM OrderItem 
     WHERE OrderItem.Order_ID=Order.Order_ID 
     AND (OrderItem.Delivery_ID IS NULL OR OrderItem.Delivery_ID=''))
ORDER BY Order_ID DESC

它可以工作,但运行速度有点慢。有没有更好的办法?

(注意,为了清楚起见,我已经重申了问题,实际的表和字段名称不同)

4

3 回答 3

1

试试这个——

SELECT 
       o.Order_ID
     , Order_status = 
               CASE WHEN ot.Order_ID IS NULL 
                    THEN 'COMPLETE' 
                    ELSE 'INCOMPLETE' 
               END
FROM dbo.[Order] o
LEFT JOIN (
     SELECT DISTINCT ot.Order_ID
     FROM dbo.OrderItem ot
     WHERE ISNULL(ot.Delivery_ID, '') = '' 
) ot ON ot.Order_ID = o.Order_ID 
于 2013-06-26T05:50:27.670 回答
1

我建议您在 Order 表上有一个列状态,并在所有订单项目交付时更新状态以完成。

这将使您的查询变得简单,以获取状态并提高性能。

于 2013-06-26T02:47:48.793 回答
1

将其放入子查询中以尝试使 case 语句不那么混乱:

SELECT Order_ID,
       CASE WHEN incomplete_count > 0 THEN 'INCOMPLETE' ELSE 'COMPLETE' END
           AS Order_status

  FROM ( SELECT o.Order_ID
               ,SUM( CASE WHEN OrderItem.Delivery_ID IS NULL OR OrderItem.Delivery_ID='' THEN 1 ELSE 0 END )
                 AS incomplete_count
           FROM Order o 
           INNER JOIN OrderItem i ON (i.Order_ID = o.Order_ID)
           GROUP by o.Order_ID
       ) x

   ORDER BY ORder_ID DESC

这个想法是每次遇到空项目时都保留一个计数器。如果总和为 0,则没有空订单项。

于 2013-06-26T02:54:36.700 回答