2017-08-04 12 views
3

問題を解決しようとしていますが、簡単な解決策が見つからないようです。私は文をいくつかのカウントに基づいて値を返すために文を使用するクエリを記述しようとしています。同じクエリでは、別のクエリでこれによって返されたデータを利用する必要があるため、オーダーIDを返す必要もあります。以下は SQL Serverの場合とgroup byによって返された行がない場合に値を返す

はクエリです:

select CASE WHEN count(name) = 0 THEN '1' ELSE CONVERT(varchar,count(name) + 1) END AS box 
, orderid 
from order 
where len(name) = 7 
and orderid = 'XYZ' 
group by orderid 

上記の問題は、あなたが想像できるよう長さ7で名前がデータ内に存在する場合、行のみが返されることです。それに関係なく有効な値を返すためにこのクエリが必要です。

長さ7の名前が存在しない場合、クエリは、1, XYZを返します。有効な長さの名前7が存在する場合、クエリは機能します。

この問題を解決するにはどうすればよいでしょうか?データは、長さ7以下の複数の名前を含むことができます。これらの名前は、トランザクションが行われた後に長さ7に変更されます。以下は

サンプルデータと希望する結果である:私はorderid = '1'のための私のクエリを実行すると

NAME  ORDERID 
ABC  001 
XYZ  001 
123  001 
OOP  002 
LMT  002 

、クエリが1, 001を返す必要があります。データは常に変化していますので、最初は上記のようになりました。取引が行われるように、データのように変更されます。この時点で

NAME   ORDERID 
    ABCABCABC  001 
    XYZ   001 
    123   001 
    OOP   002 
    LMT   002 

それが有効な行を返しますので、私は上記の私のクエリを心配する必要はありません:とき2, 001

問題がありますname列の長さが正しくない場合、クエリは何も返しません。

+0

'JOIN'とおそらくより良いフィルタの必要性の良い指標です。複数の呼び出しを行うよりも、必要なデータを取得するためにdbを1回呼び出す方がはるかに優れています。 – Shawn

+0

残念ながら、上記のテーブル/ロジックが使用されているかのように、フィルタ用に結合することはできません。結合には長さ7の名前がないため行が返されません。これは、データが存在すると解決されますが、その時点までは機能しません。 – Help123

+0

サンプルデータと望ましい結果が実際に役立ちます。 –

答えて

2

テストされていない(私はまだロジック傷や構文1を参照することはできませんが、私がテストするための環境を持っていない)あなたはこのことをお勧めします:

select convert(varchar(255), 
       sum(case when len(name) = 7 and orderid = 'XYZ' then 1 else 0 end) + 1 

        end) as box, 
     orderid 
from order 
group by orderid; 

これにより、すべてのフィルタリングロジックがselectに移動します。

それが利用できない場合は何がしたいことはカウントし、好ましくはXYZが、何か他のものであるためのIDを持つ1行の場合:他のクエリが通常であるため、データを取得するために1つのクエリからのデータを使用して

select convert(varchar(255), 
       sum(case when len(name) = 7 and orderid = 'XYZ' then 1 else 0 end) + 1 

        end) as box, 
     coalesce(max(case when orderid = 'XYZ' then orderid end), 
       max(orderid) 
       ) as orderid 
from order 
group by orderid; 
+0

私はあなたの最初のクエリが動作すると思います。私はケース句からオーダーIDを削除しました。なぜなら、すべてのオーダーの値を返し、必要なものをフィルタリングする必要があるからです。私はそのクエリを使用してテストを続けるつもりですが、私のintiialテストではそれは良いと思われる – Help123

+0

あなたはなぜ合計が使用されるのかについて少し説明できますか?ソリューションの背後にあるロジックを理解しようとしています。 orderidのグループで使用された合計は、case文の各戻り値を合計しますか? – Help123

+0

@ Help123。 。 。 'sum()'は、 'where'節にあった条件と一致する行の数を数えます。 –

0

は名前がレンス持っていないとき7は、その後、クエリの下に使用する必要があります

数(名)= 0とlen(名前)!= 7 THEN '1' ELSE CONVERT(varchar型は、カウント

選択CASE(名)ボックス AS + 1)END、B内のすべてのレコードを受注

+0

このクエリは2を返すときには機能しません。最初のチェックをスキップし、caseステートメントのELSE部分に入ります。 – Help123

0

順 受注=「XYZ」 群からかなり醜い を受注が左1枚のレコードから成るインライン・ビューに結合することにより、 XYZを取得私たちは少なくとも1つのレコードを持つことが保証されています。順序が7の長さの名前を持つ場合は、それらの値を使用します。そうでない場合、左の結合はNULLになり、インライン・ビューから値を結合します。

通常、私はこのタイプのことをUIで行います。レコードが返されない場合は、プレゼンテーションレイヤーでこれを処理します。

しかし、あなたがしなければならない場合:

SELECT coalesce(CASE WHEN count(a.name) = 0 
        THEN '1' 
        ELSE CONVERT(varchar,count(a.name) + 1) END 
       ,b.Box) AS box 
    , coalesce(a.orderid,b.orderID) 
FROM (SELECT '1' Box, 'xyz' OrderID) b 
LEFT join [order] A 
on 1=1 
and len(a.name) = 7 
and a.orderid = 'XYZ' 
GROUP BY coalesce(a.orderid,b.OrderID) 
+0

インラインビューbの列の名前が変更され、従いやすくなりました。 – xQbert

関連する問題