简化/修复长查询

时间:2014-03-23 08:07:30

标签: sql sql-server tsql

我的查询如下:

SELECT Delivery.DeliveryNumber,
       DeliveryStatus.StatusName,
       Delivery.PickupDateTime,
       Delivery.DeliveryDateTime,
       Delivery.PackageWeight,
       Delivery.PackageSize,
       Delivery.PickupAddress1,
       CASE
           WHEN Delivery.DeliveryDateTime IS NULL THEN 'Not Delivered'
           WHEN (DATEDIFF(hh, Delivery.PickupDateTime, Delivery.DeliveryDateTime) > 0)
                AND (DATEDIFF(hh, Delivery.PickupDateTime, Delivery.DeliveryDateTime) < 24) THEN 'Delivered 24hrs After Pickup'
           WHEN (DATEDIFF(dd, Delivery.PickupDateTime, Delivery.DeliveryDateTime) = 0) THEN 'Delivered Same Day'
       END AS Status
FROM Delivery
INNER JOIN DeliveryStatus ON Delivery.StatusCode = DeliveryStatus.StatusCode

此查询的问题是状态现在可以有NULL个值。我不希望Status拥有NULLs

所以我尝试添加:

WHERE (Status IS NOT NULL)但是我知道无论如何我也做不到这个......我不想这样做:

WHERE CASE
           WHEN Delivery.DeliveryDateTime IS NULL THEN 'Not Delivered'
           WHEN (DATEDIFF(hh, Delivery.PickupDateTime, Delivery.DeliveryDateTime) > 0)
                    AND (DATEDIFF(hh, Delivery.PickupDateTime, Delivery.DeliveryDateTime) < 24) THEN 'Delivered 24hrs After Pickup'
           WHEN (DATEDIFF(dd, Delivery.PickupDateTime, Delivery.DeliveryDateTime) = 0) THEN 'Delivered Same Day'

有没有办法清理查询?

我的任务是设计一个查询,使其返回满足以下条件的行:

  • 已提取但尚未送达的包裹
  • 在取件后一天内交付的包裹(少于24小时)
  • 已在提取当天送达的包裹
  • 在取件前一天(24小时内)送达的包裹

我认为我的查询正确。我只是需要帮助清理它,因为它看起来很脏。有什么想法吗?

编辑:添加了整个数据结构:

enter image description here

1 个答案:

答案 0 :(得分:1)

所以你的问题是你不想两次编码相同的逻辑(一次在where子句中,一次在选择列表中)。您可以使用外部查询从您已有的行中选择所需的行来解决此问题:

SELECT *
FROM 
(
  SELECT Delivery.DeliveryNumber,
         DeliveryStatus.StatusName,
         Delivery.PickupDateTime,
         Delivery.DeliveryDateTime,
         Delivery.PackageWeight,
         Delivery.PackageSize,
         Delivery.PickupAddress1,
         CASE
             WHEN Delivery.DeliveryDateTime IS NULL THEN 'Not Delivered'
             WHEN (DATEDIFF(hh, Delivery.PickupDateTime, Delivery.DeliveryDateTime) > 0)
                  AND (DATEDIFF(hh, Delivery.PickupDateTime, Delivery.DeliveryDateTime) < 24) THEN 'Delivered 24hrs After Pickup'
             WHEN (DATEDIFF(dd, Delivery.PickupDateTime, Delivery.DeliveryDateTime) = 0) THEN 'Delivered Same Day'
         END AS Status
  FROM Delivery
  INNER JOIN DeliveryStatus ON Delivery.StatusCode = DeliveryStatus.StatusCode
)
WHERE Status IS NOT NULL;