2017-12-22 15 views
-1

私は非常に簡単な質問がありますが、答えを見つけ出すことができません。同じテーブル内でクエリを適用するにはどうすればよいですか?

declare @Register table (Citizen nvarchar(50), Role nvarchar(10), Process nvarchar(10)) 

insert @Register values 
     ('A', 'seller' , 'Process1') 
    , ('A', 'seller' , 'Process1') 
    , ('A', 'seller' , 'Process1') 
    , ('A', 'seller' , 'Process2') 
    , ('A', 'buyer' , 'Process3') 
    , ('A', 'seller' , 'Process3') 
    , ('B', 'seller' , 'Process3') 
    , ('B', 'seller' , 'Process4') 
    , ('C', 'seller' , 'Process4') 

私は出品者と出品者など、さまざまなプロセスの数として複数のプロセスで対話市民を抽出する方法を思ったんだけど:

は、私は、次の表を持っています。また、出力テーブルにProcessNumberを追加する(たとえば、市民が3つの異なるプロセスで売り手だった場合、プロセスごとに1つの行が生成されます。この場合、3。その人が売り手として関わったプロセスを表示します)。この市民は売り手だっ異なるプロセスの数(この中では、例を挙げ市民が異なる3つのプロセスでは、売り手だったので、それは、3になるでしょう)

だから、結果は次のようになります。

Citizen | Process | Number_Of_Diff_Process_as_Seller 
    -----------+----------+------------------------------------ 
    A   | Process1 | 3 
    A   | Process2 | 3 
    A   | Process3 | 3 
    B   | Process3 | 2 
    B   | Process4 | 2 
+0

予想される出力の説明が回答に表示された出力の例と一致しません。どちらか一方を変更して一貫性を持たせることはできますか、ありがとうございます。 –

+0

私の編集した質問を追加しました。私が言及したこの出力表を入手したいと思います。 – GeoMaps

+1

あなたの出力はあなたの説明とあなたの提供されたサンプルデータとは一致しません。あなたの出力の 'A | 2 | 3 ?? –

答えて

1
SELECT DISTINCT a.Citizen, a.Process, b.Number_Of_Diff_Process_as_Seller 
FROM @Register a 
INNER JOIN (SELECT Citizen, COUNT(DISTINCT Process) Number_Of_Diff_Process_as_Seller FROM @Register WHERE Role = 'seller' GROUP BY Citizen) b 
ON a.Citizen = b.Citizen 
WHERE a.Role = 'seller' AND b.Number_Of_Diff_Process_as_Seller> 1 

市民1人当たりのプロセス数が各レコードに必要な理由は分かりませんが、範囲外です。

+0

ありがとうございました。完璧なソリューション。あなたの幸せを祈ります。 ;) – GeoMaps

1
select t.Citizen,Process,Number_Of_Diff_Process_as_Seller 
    from t 
    join (select Citizen, count(distinct Process) as Number_Of_Diff_Process_as_Seller 
      from t 
      where Role = 'seller' 
      group by Citizen) c 
    on t.Citizen = c.Citizen 
    group by t.Citizen, Process 
    having Number_Of_Diff_Process_as_Seller > 1; 
0

ここにJOINは必要ありません。まっすぐ分析関数は、あなたが必要なものを見つけることができます...

SELECT 
    * 
FROM 
(
    SELECT 
     citizen, 
     process, 
     COUNT(*) OVER (PARTITION BY citizen) AS unique_seller_process_count 
    FROM 
     register 
    WHERE 
     role = 'seller' 
    GROUP BY 
     citizen, 
     process 
) 
    filtered_summary 
WHERE 
    unique_seller_process_count > 1 

http://sqlfiddle.com/#!6/53de2/2

だけ一度データをスキャンするので、あなたが持っているより多くのデータより明らかになるジョインを持っていないの利点( 2回ではなく)、既に解析した行を再検索する必要はなく、DISTINCTキーワードに高価な並べ替えを適用する必要はありません。

適切なインデックス(上記のsqlfiddleに示されています)と組み合わせると、Analytical Functionのアプローチがあらゆるデータセットのサイズに対して最も高速になる可能性があります。

  • SQLFiddleもあなたはどちらの計画はいずれも計画がNESTED LOOP (INNER JOIN)
  • このソリューションはINDEX SEEK(すでに全体的なコストを半減させる)
  • を回避してい
  • を持って
  • 実行計画を見ることができます
  • この解決法は、DISTINCT SORT(コストを半分にするよりも良い)を回避する。

全体のコスト結果は、この回答の全体コストがの105.3%で、代替コストがインデックススキャンの550%を超えるためです。

関連する問題