2016-10-05 9 views
1

1つのテーブルの自己結合後のレコードが特定の条件を持っていれば、2番目のテーブルに存在しないように2つのテーブルをスキャンするクエリを書く必要があります。自己結合と結合なし

参照が受信された場合、参照の組み合わせ(data1、data2、reference、identifier)に固有の制約を持つUniqueReferenceテーブルに挿入されます しかし、その注文は却下またはキャンセルされ、次の注文には同じ参照組み合わせ。私はまだそれを許可することを確認する必要があります。

Iは、テストデータについては、以下の例を与える:

UniqueReference Table 
------- 
sequence data1 data2 key reference identifier 
1   XYZB ABCD 234 Reference1 ID2 
2   XYZB DCBF 456 Reference2 ID2 
3   XYZB null 678 Reference3 null 
4   XYZB ABCD 980 Reference1 ID2 

Order Table 
-------- 
sequence key status 
1  234 Created 
2  456 Rejected 
3  789 Processed 
4  980 Cancelled 
5  678 Processing 

今は注文を受信したときに設定された2つのデータ上で(ID2、XYZB、ABCD、参照編)基準組合せで(SOキー980と言う)をシステムはそのステータスが拒否されていないキー(234)でこのような注文を受け取ったので、その注文を許可すべきではありません(重複しています)。しかし、組合せ(XYZB、DCBF、Reference2、ID2)で新しい注文を受け取った場合、システムでその注文を持っているがステータスが拒否されているため、この注文を許可する必要があります。

私は私はあなたが主にこの設定を自分で混乱していると思う

Select count(*) from Order o where o.status <> 'Rejected' and o.key in 
(select <self-join> on reference combination on key for newly received order) 
+1

あなたはこれら4つのカラムにユニーク制約がある場合、あなたは* *重複する行を許可することはできません期待される出力を示し、また、あなたが – TheGameiswar

+0

を使用しているDBMSにタグを付けてください。したがって、私はあなたの質問を理解していません。そのユニーク制約は最初のテーブルについてのみ知っていて、別のテーブルが何かが「拒否」されていると言っても気にしません。これを削除するか、一意制約に列を追加する必要があります。 –

+0

混乱を避けるため、キーワードを識別子として使用しないようにしてください( 'order、key、sequence') – joop

答えて

0

のようなものを必要としています。 UniqueReferenceテーブルについては、 data1, data2, reference, identifierの組み合わせがユニークであるとすれば、単なるそれであるはずです:ユニーク。他の場所で何が起こるかは問題でもなく、気にする必要もありません。

備考:私はkeyフィールドもユニークであると仮定していますが、もしそうならば、あなたは今なぜ自軍番号/身分証明書を使用していないのでしょうか? sequence列には、実際値IMHOはありません。今、私はあなたがこれらの値をどのように生産したかを知ることができません。

Orderテーブルの場合、ここでは、まだこのkeyの前回のレコードがない場合は、INSERT操作を許可するという論理があります。前のものがある場合は、最新のものを探し、「取り消された」と表示されたら、INSERTも許可します。それ以外の場合は常にINSERTをブロックします。

私はあなたがこれをやりたいかどうかはわかりませんが、この場合はストアドプロシージャが意味をなさないと思います。

PS:このコードは完璧ではありません(初心者はテストされていません)、エラー処理がなく、多少最適化することができます(たとえば、特定の操作をマージしたり、しかし、私はその冗長さは読みやすく、早すぎる最適化はすべての悪の根源であるため、最初にこのように作業し、遅すぎると必要に応じて最適化したいと思うかもしれないと思います。

(あなたはRDBMSを言及していなかったので、私はT-SQL構文を使用していますが、私はマイナーな調整と、ほとんどのシステム上で実行するのに十分な汎用的だと思う...)

CREATE PROCEDURE p_insert_order (
            @data1  varchar(100), 
            @data2  varchar(100), 
            @reference varchar(100), 
            @identifier varchar(100), 
            @status  varchar(100) 
           ) 
AS 

    DECLARE @key   int, 
      @is_new_key bit, 
      @allow_insert bit, 
      @last_status varchar(100) 

    SELECT @key = NULL, 
      @is_new_key = 0, 
      @allow_insert = 0, 
      @last_status = NULL 


    BEGIN TRANSACTION 

     -- do we already have a key for this combination? 
     SELECT @key = [key] 
      FROM [UniqueReference] WITH (UPDLOCK, HOLDLOCK) 
     WHERE data1  = @data1  
      AND data2  = @data2  
      AND reference = @reference 
      AND identifier = @identifier 

     IF @key IS NULL 
      BEGIN 
       SELECT @is_new_key = 1, 
         @key = 0 -- ??? -- I have no clue how you come up with these so I'm going to leave it open 

       INSERT [UniqueReference] (data1, data2, reference, identifier, [key]) 
       VALUES (@data1, @data2, @reference, @identifier, @key) 
      END 

     -- do we allow insert? 
     SELECT @allow_insert = @is_new_key 

     IF @allow_insert = 0 
      BEGIN 
       SELECT TOP 1 @last_status = [status] 
        FROM [Order] WITH (UPDLOCK, HOLDLOCK) 
       WHERE [key] = @key 
       ORDER BY sequence DESC 

       SELECT @allow_insert = 1 
       WHERE @last_status IS NULL 
        OR @last_status = 'Rejected' 
      END 

     -- do we do insert? 
     IF @allow_insert = 1 
      BEGIN 

       INSERT [Order] ([key], [status]) 
       VALUES (@key, @status) 

      END 

    COMMIT TRANSACTION 

    Return(0) 

PS:予約語を使用しないようにしてください。Orderkeystatus、...

0

あなたはそれが(DATA1、DATA2、参照、識別子、キー)になりますので、一意制約にUniqueReference表にkey列を追加する必要がまず第一に

その後、このクエリに

;with 
old_orders as (
    select distinct data1, data2, [reference], [identifier] 
    from UniqueReference u 
    where not exists(select top 1 1 from Order o where u.[key] = o.[key] and o.status in ('Cancelled','Rejected')) 
) 
insert into @UniqueReference (data1, data2, [reference], [identifier], [key]) 
select @data1, @data2, @reference, @identifier, @key 
where exists (
    select @data1, @data2, @reference, @identifier 
    except 
    select * from old_orders o 
) 
を使用することができますこれらの値で

は、インサートは、インサートが受け入れられるこれらの値で

declare 
    @data1 varchar(4)='XYZB', 
    @data2 varchar(4)='ABCD', 
    @key int = 980, 
    @reference varchar(10)='Reference1', 
    @identifier varchar(4)='ID2' 

を拒否されます

declare 
    @data1 varchar(4)='XYZB', 
    @data2 varchar(4)='DCBF', 
    @key int = 999, 
    @reference varchar(10)='Reference2', 
    @identifier varchar(4)='ID2' 
関連する問題