2016-04-13 24 views
0

2つのフィールド(ContractState、TransID)に基づいて一致するレコードがないテーブルでデータを検索したいとします。例えば一致するレコードがないテーブルのデータのみを検索するSQL

、(すべてのデータセットは、レコードの数百人が含まれている現実に、私はほんの数を含めています)、このデータセットを前提としています

AccountNbr ContractState TransID  Product 
3335477  AL    80079  DPPO, DHMO 
3335477  AL    80080  PPO 
3335477  AR    80079  DPPO, DHMO 
3335477  AR    80080  PPO 

2つのレコードがあるので、これは、0のレコードを返す必要がありますAL(各TransIDに1つ)とARに対して2つのレコードがあります。各状態のため、唯一の1 TRANSIDがあるため

AccountNbr ContractState TransID  Product 
3335477  DE    80079  DHMO 
3335477  WA    80080  DHMO 

:私は、次のデータセットを返したい

AccountNbr ContractState TransID  Product 
3335477  AL    80079  DPPO, DHMO 
3335477  AL    80080  PPO 
3335477  DE    80079  DHMO 
3335477  WA    80080  DHMO 

ただし、次のデータセットを与えられました。

私はこのコードを持っているが、それはまた、データが一致するレコードが含まれています

SELECT 
    'tblSQLContractState' as TableName, 
    TransID, 
    ContractState, 
    Product, 
    COUNT(*) AS [NumOfMessage] 
FROM tblSQLContractState 
WHERE TransID IN (80079, 80080) 
GROUP BY 
    TransID, 
    ContractState, 
    Product 
HAVING COUNT(*) = 1 
+0

3つの答えはすべていいですし、うまくいきましたが、私はGordonの編集した方がいいと思ったので、20の異なる表について同様のクエリを実行しています。入力のおかげで、皆さん! –

+0

それを受け入れる:) –

答えて

1

使用ウィンドウ関数を。あなたが提供されたデータについては、これは動作するはずです:

select cs.* 
from (select cs.*, 
      count(*) over (partition by AccountNbr, ContractState) as cnt 
     from tblSQLContractState cs 
     where TransID IN (80079, 80080) 
    ) cs 
where cnt = 1; 
1

あなたはこのContractStateでこのTransIdではなく、と別のレコードがある場合、レコードを選択するために、NOT EXISTSを使用することができます。

SELECT 
    'tblSQLContractState' as TableName, 
    cs.AccountNbr, cs.ContractState, cs.TransID, cs.Product 
FROM tblSQLContractState cs 
WHERE cs.TransID IN (80079, 80080) 
AND NOT EXISTS         -- no other record 
(
    SELECT 1 FROM tblSQLContractState cs2 
    WHERE cs2.TransID <> cs.TransID    -- with other TransId 
     AND cs2.ContractState = cs.ContractState -- and this ContractState 
) 

NOT EXISTS非常に効率的ですSQL-Serverでは簡単に変更/拡張できます。もう1つの利点は、GROUP BYではなく、すべての列を選択できることです。

1

あなたの質問は終了しました。しかし、ContractStateごとに1つの結果行が必要です。また、レコードの数(集計COUNT(*))を知りたいこの属性です。したがって、GROUP BY句からProductTransIDを削除してください。

表示する行数が1の組み合わせのみですので、MIN(Product)またはMAX(Product)を使用して問題の1つの製品を取得できます。 TransIDと同じです。

SELECT 
    'tblSQLContractState' as TableName, 
    MAX(TransID) AS TransID, 
    ContractState, 
    MAX(Product) AS Product, 
    COUNT(*) AS [NumOfMessage] 
FROM tblSQLContractState 
WHERE TransID IN (80079, 80080) 
GROUP BY ContractState 
HAVING COUNT(*) = 1; 

ゴードンの答えは、もっと簡単で一般的な使用です。私の意見ではこれを解決するための自然な方法です。あなたの質問が非常に近いことを示すだけでした:-)

更新:Timの回答もとても良いです。 (私が入力したときはそこにはなかった。)彼は正しい。 ContractStateの別のレコードが存在するかどうかだけ知りたいので、exists節が適切です。

関連する問題