基于子表的计算摘要字段

时间:2013-06-26 02:40:03

标签: sql-server tsql ado.net

我有两个表,OrderOrderItemOrder.Order_ID=OrderItem.Order_ID

上有一对多的关系

我想要一个查询返回一个列表,显示每个Order,COMPLETE或INCOMPLETE的状态。

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

它有效,但运行有点慢。还有更好的方法吗?

(N.B。为了清晰起见我重申了问题,实际的表和字段名称不同)

3 个答案:

答案 0 :(得分:1)

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

这将简化您的查询以获取状态并提高性能。

答案 1 :(得分: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,则没有空订单项。

答案 2 :(得分: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