3

编辑:人们很难理解我想要什么。所以这里有漂亮的图片来解释它的细节。

首先将Transactions加入Strange

在此处输入图像描述

到目前为止的结果

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
+----------+
|          |
|          | 
|          |
|          |
|          |
|          |
|          |
+----------+

我希望此表中的每一行仅加入一个可能的匹配表:

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

单个事务完全有可能在多个表中具有匹配的条目。但是对于其他表的每个可能的JOINTransactions我希望 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 回答