2016-10-18 7 views
1

異なるアドレスの注文の一覧があるとします。
各注文記録には、独自のステータスとサービス日付があります。
ステータスはint型の列挙型です。 「10」は提出を意味し、「2」は保留中、「3」は承認済み、「6」は完了していることなどを意味する「1,2,3,4,5,6,7,8,9,10」。
我々は、新しい注文の作成に前の注文のコンテンツを再利用する機能を持っています。この目的のために、現在の注文と同じ住所とサービスタイプを持つ最新の注文記録を見つける必要があります。
しかしもう一つ事があります。 注文ステータスに基づいて最新のレコードを見つける必要があります。まず、「完了」ステータスを持つ注文に興味があります。そのような注文がない場合は、「承認済み」ステータスの注文を検索したいと考えています。それから、「提出された」など。SQL Serverでレコードが見つかるまで追加の条件を適用してレコードを選択する

これまでのところ、私は次の解決策を作ってみた:

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; 

は、任意のより良い(より最適化された)解決策はありますか?

+0

ここには改善の余地がありますが、テーブルのコンテキストなしでコードを提供することは不可能です。ここから始めましょう。 http://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/ –

+0

「最新の」注文を選択する際の優先順位は、serviceDateまたは注文ステータス?たとえば、昨日の注文に「4」のステータス(完了)があり、今日の注文に「3」のステータス(保留中)がある場合、その注文を「最新」として選択する必要がありますか? – JohnH

+0

@ JohnH、注文状況が優先されます。 –

答えて

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 
+0

難易度は順序ステータスです。列挙は私の例で述べたより複雑です。ステータスは優先順位でソートされていないので、最初にステータス= 6のオーダーを選択し、次にそれぞれステータス2,3,1,10,9のオーダーを検索する必要があります。 –

+0

編集したコードサンプルでは、​​それぞれ6,3,2および4のステータスしか考慮されていません。しかし、私が理解しているように、あなたの優先順位は、あなたの例に矛盾する6,2,3,1,10および9でなければなりません。解決策を見つける前に、私は最初に正確な優先順位を明確にするのが好きです。 –

+0

はい、正しく理解しています。簡単にするために私の例では4つのステータスしか提供していません。 –

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 
関連する問題