通过应用其他条件选择记录,直到在SQL Server中找到记录

时间:2016-10-18 19:54:08

标签: sql-server

我们假设我们有一份不同地址的订单清单 每个订单记录都有自己的状态和服务日期 Status是一个int枚举,例如" 1,2,3,4,5,6,7,8,9,10",其中" 10"意味着提交," 2"待定," 3"已获批准," 6"已完成等 我们有一项功能,可以在创建新订单时重复使用先前订单的内容。为此,我们需要找到与当前订单具有相同地址和服务类型的最新订单记录 但还有一件事。 我们需要根据订单状态找到最新记录。首先,我们感兴趣的是已经完成了#39;状态。如果没有此类订单,我们希望通过“已批准”的订单查找订单。状态。然后提交'等等。

到目前为止,我已经提出了下一个解决方案:

declare @date datetime = '2016-10-18';  
declare @serviceType varchar(20) = 'delivery';  
declare @zipCode int = 99999;  

WITH cte AS (  
  SELECT * FROM Order AS O  
  WHERE O.serviceDate <= @date AND  
  O.serviceType = @serviceType AND  
  O.zipCode = @zipCode)  

/* find order for content re-using */  
SELECT TOP 1 * FROM cte  
WHERE status =   
  CASE   
  WHEN 0 < (SELECT COUNT(1) FROM cte  
  WHERE Status = 6) /* completed */  
  THEN 6  
  WHEN 0 < (SELECT COUNT(1) FROM cte  
  WHERE Status = 3) /* approved */  
  THEN 3  
  WHEN 0 < (SELECT COUNT(1) FROM cte  
  WHERE Status = 2) /* pending */  
  THEN 2  
  WHEN 0 < (SELECT COUNT(1) FROM cte  
  WHERE Status = 10) /* submitted */  
  THEN 10    
  END  
ORDER BY serviceDate DESC;  

有更好的(更优化的)解决方案吗?

2 个答案:

答案 0 :(得分:0)

我假设您的查询返回正确的结果,正确的优先级是6,3,2,1,9,10。相应地更改订单。 请尝试以下更清洁的代码。

DECLARE @date datetime = '2016-10-18';  
DECLARE @serviceType varchar(20) = 'delivery';  
DECLARE @zipCode int = 99999;  

    SELECT  TOP (1) *  
    FROM [dbo].[Order] AS O  
    WHERE O.serviceDate <= @date AND  
          O.serviceType = @serviceType AND  
          O.zipCode = @zipCode AND  
          Status  IN (SELECT  Status  FROM [dbo].[Order] M GROUP BY (M.Status  ) HAVING COUNT(*)>=1 )    

          ORDER BY CASE WHEN Status  = 6 THEN 1
              WHEN Status  =2 THEN 2
              when Status  = 3THEN 3
              when Status  = 1 THEN 4
              when Status  = 9 THEN 5
               when Status  = 10 THEN 6 END ASC,
         serviceDate  DESC

答案 1 :(得分:0)

经过深思熟虑后,我想出了下一个解决方案。

select top 1 *, 
  CASE 
      WHEN so.WP_GenericStatus = 6 THEN 1
      WHEN so.WP_GenericStatus = 3 THEN 2
      WHEN so.WP_GenericStatus = 2 THEN 3
      WHEN so.WP_GenericStatus = 10 THEN 4
      ELSE 5
  END AS 'Priority'  
  FROM Order AS O
  WHERE O.serviceDate <= @date and 
  O.serviceType = @serviceType and
  O.zipCode = @zipCode 
  ORDER BY 'Priority' ASC, serviceDate DESC