3

編集:人々は私が何を望んでいるのか理解するのに苦労しています. だから、ここにそれを耐え難いほど詳細に説明するきれいな写真があります.

最初にTransactionsStrangeに結合します。

ここに画像の説明を入力

これまでの結果

Customer  Invoice  TransactionID  Mass  Length                LeptonNumber
========  =======  =============  ====  ====================  ============
Ian       One      1              Ian   Judgement Spaulders   50
Ian       One      1              Ian   Glorious Breastplate  50
Chris     Two      2              Chris Barenavel             2

次に、残りの行をDownで結合してみます:

ここに画像の説明を入力

これまでの結果

Customer  Invoice         TransactionID  Mass  Length                LeptonNumber
========  =======         =============  ====  ====================  ============
Ian       One             1              Ian   Judgement Spaulders   50
Ian       One             1              Ian   Glorious Breastplate  50
Chris     Two             2              Chris Barenavel             2
Jamie     Krol Blade      3              Jay   Krol Blade            90
Jay       Arcanite Reaper 4              Ian   Arcanite Reaper       90

最後に、残りの行をCharmedに結合します。

ここに画像の説明を入力

これまでの結果

Customer  Invoice         TransactionID  Mass    Length                LeptonNumber
========  =======         =============  ====    ====================  ============
Ian       One             1              Ian     Judgement Spaulders   50
Ian       One             1              Ian     Glorious Breastplate  50
Chris     Two             2              Chris   Barenavel             2
Jamie     Krol Blade      3              Jay     Krol Blade            90
Jay       Arcanite Reaper 4              Ian     Arcanite Reaper       90
Potatoe   Dan Quayle      5              Potatoe Dan Quayle            90

そして、残った行を見てみましょう:

ここに画像の説明を入力

希望する結果セットを提供する

Customer  Invoice         TransactionID  Mass    Length                LeptonNumber
========  =======         =============  ====    ====================  ============
Ian       One             1              Ian     Judgement Spaulders   50
Ian       One             1              Ian     Glorious Breastplate  50
Chris     Two             2              Chris   Barenavel             2
Jamie     Krol Blade      3              Jay     Krol Blade            90
Jay       Arcanite Reaper 4              Ian     Arcanite Reaper       90
Potatoe   Dan Quayle      5              Potatoe Dan Quayle            90
Stapler   Alexstraza      6              NULL    NULL                  NULL

私はメインテーブルを持っています:

Transactions
+----------+
|          |
|          | 
|          |
|          |
|          |
|          |
|          |
+----------+

このテーブルの各行が、一致する可能性のあるテーブルを1 つだけ結合するようにします。

Tranasctions        Strange
+----------+      +----------+
| row 1 ===|=====>| row 1    |         Down
| row 2 ===|=====>| row 2    |       +---------+
| row 3 ===|======+----------+======>| row 1   |        Charmed
| row 4 ===|========================>| row 2   |       +---------+
| row 5 ===|=========================+---------+======>| row 1   |
| row 6 ===|==========================================>| row 2   |
+----------+                                           +---------+

通常、次Transactionsのセットへの結合として実行しますStrange || Down || Charmed

SELECT
   Transactions.*,
   Quarks.Mass,
   Quarks.Length,
   Quarks.LeptonNumber
FROM Transactions
    INNER JOIN NationalSecurityLetters
    ON Transactions.TransactionID = NationalSecurityLetters.ReferenceNumber

    LEFT JOIN (
       SELECT 'Strange' AS Type, * FROM Strange
       UNION ALL
       SELECT 'Down' AS Type, * FROM Down
       UNION ALL
       SELECT 'Charmed' AS Type, * FROM Charmed
    ) Quarks
    ON (
        (Quarks.Type = 'Strange' AND Transactions.Customer = Quarks.Mass)
        OR
        (Quarks.Type = 'Down' AND Transactions.Invoice = Quarks.Length)
        OR
        (Quarks.Type = 'Charmed' AND Transactions.Customer = Quarks.Length)    
    )       

問題は、結合をその優先順序で実行したいということです:

  • Strange
  • Down
  • Charmed

1 つのトランザクションが複数のテーブルに一致するエントリを持つことは十分に可能です。しかし、他のテーブルへの可能なJOINごとTransactionsに、SQL Serverがテーブルを優先するようにしStrangeます。一致しない場合は、Downテーブルに移動します。Charmedテーブルに行く一致がない場合。

If you find a match in      Prefer the matching row from
==========================  ============================
Strange                     Strange
Strange and Down            Strange
Strange, Down, and Charmed  Strange
Down                        Down
Down and Charmed            Down
Charmed                     Charmed
(no match?)                 (then there's no match)

私はOPTION(FORCE ORDER)句を使用することを考えました:

SELECT *
FROM Transactions
    INNER JOIN NationalSecurityLetters
    ON Transactions.TransactionID = NationalSecurityLetters.ReferenceNumber

    LEFT JOIN (
       SELECT 'Strange' AS Type, * FROM Strange
       UNION ALL
       SELECT 'Down' AS Type, * FROM Strange
       UNION ALL
       SELECT 'Charmed' AS Type, * FROM Strange
    ) Quarks
    ON (
        (Quarks.Type = 'Strange' AND Transactions.Customer = Quarks.Mass)
        OR
        (Quarks.Type = 'Down' AND Transactions.Invoice = Quarks.Length)
        OR
        (Quarks.Type = 'Charmed' AND Transactions.Customer = Quarks.Length)    
    )       
OPTION (FORCE ORDER)

しかし、SQL Server を強制的に参加させたくありません。

  • Transactions==> NationalSecurityLetters、参加する方が有利な場合
  • NationalSecurityLetters==>Transactions

4

2 に答える 2

4

@AaronBertrandが述べたように、あなたが何をしようとしているのかは少しわかりませんが、出力の変更について話している場合は、COALESCEを使用できますか? 例:

SELECT COALESCE(s.Value, d.Value, c.Value), t.*
FROM Transactions as t
LEFT JOIN Strange as s
ON t.id = s.tid
LEFT JOIN Down as d
ON t.id = d.tid
LEFT JOIN Charmed as c
ON t.id = c.tid
于 2012-09-19T22:35:16.717 に答える
1

多分この解決策はあなたを助けるでしょう:

SET ANSI_WARNINGS ON;
GO
BEGIN TRAN;

CREATE TABLE dbo.TableA (
    TableAID INT PRIMARY KEY,
    DescriptionA VARCHAR(50) NOT NULL
);
INSERT dbo.TableA 
VALUES (1,'A-1'), (2,'A-2');

CREATE TABLE dbo.TableB (
    TableBID INT PRIMARY KEY,
    DescriptionB VARCHAR(50) NOT NULL
);
INSERT dbo.TableB
VALUES (1,'B-1'), (2,'B-2'), (4,'B-4');

CREATE TABLE dbo.TableC (
    TableCID INT PRIMARY KEY,
    DescriptionC VARCHAR(50) NOT NULL
);
INSERT dbo.TableC
VALUES (1,'C-1'),(3,'C-3'), (4,'C-4');
GO

CREATE TABLE dbo.[Transaction] (
    TransactionID INT IDENTITY PRIMARY KEY,
    TranDate DATE NOT NULL,
    Col1 INT NULL
);
INSERT dbo.[Transaction]
VALUES ('20120101', 1), ('20120202',2), ('20120303',3), ('20120404',4), ('20120505',5);
GO

SELECT  *
FROM    dbo.[Transaction] t
OUTER APPLY (
    SELECT * FROM TableA a WHERE t.Col1=a.TableAID
) j1 --first join
OUTER APPLY (
    SELECT * FROM TableB b WHERE j1.TableAID IS NULL AND t.Col1=b.TableBID --First condition will force the join order (dbo.TableA.TableAID should be NOT NULL)
) j2 --second join
OUTER APPLY (
    SELECT * FROM TableC c WHERE j1.TableAID IS NULL AND j2.TableBID IS NULL AND t.Col1=c.TableCID ---First two conditions will force the join order (dbo.TableA.TableAID & dbo.TableB.TableBID should be NOT NULL)
) j3 --third join
WHERE   j1.TableAID IS NOT NULL
OR      j2.TableBID IS NOT NULL
OR      j3.TableCID IS NOT NULL

ROLLBACK;

この場合、結合順序は次のとおりです。

1) t.Col1=a.TableAID

2) そうでない場合 1) t.Col1=b.TableBID

3) 1) および 2) ではない場合、t.Col1=c.TableCID

結果:

TransactionID TranDate   Col1 TableAID DescriptionA TableBID DescriptionB TableCID DescriptionC
------------- ---------- ---- -------- ------------ -------- ------------ -------- ------------
1             2012-01-01 1    1        A-1          NULL     NULL         NULL     NULL
2             2012-02-02 2    2        A-2          NULL     NULL         NULL     NULL
3             2012-03-03 3    NULL     NULL         NULL     NULL         3        C-3
4             2012-04-04 4    NULL     NULL         4        B-4          NULL     NULL
于 2012-09-20T02:02:28.427 に答える