sql - 自 FULL OUTER JOIN 的替代方案以获得两个条目之间的匹配

标签 sql sql-server outer-join self-join

在我的数据库模型中,我有两个实体:Entitlement 和 Entitlement_Data。每个权利由递增的 ID (IDENTITY) 标识,并且可以有多个 Entitlement_Data 条目,每个条目具有不同的 Type - 可以是 0(每周)或 1(每月)(对于 Entitlement_Data,EntitlementID 和 Type 是 PK,EntitlementID 是 FK到权利表)。 对于每项权利,我需要:

  1. 对于给定的一组 Entitlement_Data 属性(SharesPaid、LocalTaxRate 等),从每月 (Type=1) 或每周 (Type=0) Entitlement_Data 中获取第一个非 NULL 值 - 该属性的第一部分选择;
  2. 获取有关每月和每周 Entitlement_Data 条目(SharesPaid_Match 等)之间匹配/不匹配的一些指示 - SELECT 的最后部分。

这是我正在使用 atm 的查询:

SELECT 
    COALESCE(MD.EntitlementID, WD.EntitlementID) AS EntitlementID,
    COALESCE(MD.LocalTaxRate, WD.LocalTaxRate) AS LocalTaxRate,
    COALESCE(MD.SharesPaid, WD.SharesPaid) AS SharesPaid,
    COALESCE(MD.LocalTaxAmount, WD.LocalTaxAmount) AS LocalTaxAmount,
    COALESCE(MD.LocalTaxEquivalent, WD.LocalTaxEquivalent) AS LocalTaxEquivalent,
    COALESCE(MD.NetReceived, WD.NetReceived) AS NetReceived,
    COALESCE(MD.LocalTaxCurrency, WD.LocalTaxCurrency) AS LocalTaxCurrency,
    COALESCE(MD.Currency, WD.Currency) AS Currency,
    COALESCE(MD.ReleaseDate, WD.ReleaseDate) AS ReleaseDate,
    (
        CASE
            WHEN MD.LocalTaxEquivalent IS NULL OR WD.LocalTaxEquivalent IS NULL THEN NULL
            WHEN MD.LocalTaxEquivalent <> WD.LocalTaxEquivalent THEN 0
            ELSE 1
        END
    ) AS LocalTaxEquivalent_Match,
    (
        CASE
            WHEN MD.NetReceived IS NULL OR WD.NetReceived IS NULL THEN NULL
            WHEN MD.NetReceived <> WD.NetReceived THEN 0
            ELSE 1
        END
    ) AS NetReceived_Match,
    (
        CASE
            WHEN MD.SharesPaid IS NULL OR WD.SharesPaid IS NULL THEN NULL
            WHEN MD.SharesPaid <> WD.SharesPaid THEN 0
            ELSE 1
        END
    ) AS SharesPaid_Match,
    (
        CASE
            WHEN MD.Currency IS NULL OR WD.Currency IS NULL THEN NULL
            WHEN MD.Currency <> WD.Currency THEN 0
            ELSE 1
        END
    ) AS Currency_Match,
    (
        CASE
            WHEN MD.DividendRate IS NULL OR WD.DividendRate IS NULL THEN NULL
            WHEN MD.DividendRate <> WD.DividendRate THEN 0
            ELSE 1
        END
    ) AS DividendRate_Match,
    (
        CASE
            WHEN MD.LocalTaxRate IS NULL OR WD.LocalTaxRate IS NULL THEN NULL
            WHEN MD.LocalTaxRate <> WD.LocalTaxRate THEN 0
            ELSE 1
        END
    ) AS LocalTaxRate_Match
FROM 
    Entitlement_Data MD
    FULL OUTER JOIN Entitlement_Data WD
        ON MD.EntitlementID = WD.EntitlementID
WHERE
    WD.Type = 0 AND MD.Type = 1

有没有办法避免 FULL OUTER JOIN 并获取我需要的信息?我评估了 GROUP BY 的使用,但似乎没有得到我需要的结果。 谢谢。

最佳答案

为什么不将连接left join到“主表”,它是Entitlement,如以下代码所示:

select
    COALESCE(MD.EntitlementID, WD.EntitlementID) AS EntitlementID,
    COALESCE(MD.LocalTaxRate, WD.LocalTaxRate) AS LocalTaxRate,
    COALESCE(MD.SharesPaid, WD.SharesPaid) AS SharesPaid,
    COALESCE(MD.LocalTaxAmount, WD.LocalTaxAmount) AS LocalTaxAmount,
    COALESCE(MD.LocalTaxEquivalent, WD.LocalTaxEquivalent) AS LocalTaxEquivalent,
    COALESCE(MD.NetReceived, WD.NetReceived) AS NetReceived,
    COALESCE(MD.LocalTaxCurrency, WD.LocalTaxCurrency) AS LocalTaxCurrency,
    COALESCE(MD.Currency, WD.Currency) AS Currency,
    COALESCE(MD.ReleaseDate, WD.ReleaseDate) AS ReleaseDate,
    (
        CASE
            WHEN MD.LocalTaxEquivalent IS NULL OR WD.LocalTaxEquivalent IS NULL THEN NULL
            WHEN MD.LocalTaxEquivalent <> WD.LocalTaxEquivalent THEN 0
            ELSE 1
        END
    ) AS LocalTaxEquivalent_Match,
    (
        CASE
            WHEN MD.NetReceived IS NULL OR WD.NetReceived IS NULL THEN NULL
            WHEN MD.NetReceived <> WD.NetReceived THEN 0
            ELSE 1
        END
    ) AS NetReceived_Match,
    (
        CASE
            WHEN MD.SharesPaid IS NULL OR WD.SharesPaid IS NULL THEN NULL
            WHEN MD.SharesPaid <> WD.SharesPaid THEN 0
            ELSE 1
        END
    ) AS SharesPaid_Match,
    (
        CASE
            WHEN MD.Currency IS NULL OR WD.Currency IS NULL THEN NULL
            WHEN MD.Currency <> WD.Currency THEN 0
            ELSE 1
        END
    ) AS Currency_Match,
    (
        CASE
            WHEN MD.DividendRate IS NULL OR WD.DividendRate IS NULL THEN NULL
            WHEN MD.DividendRate <> WD.DividendRate THEN 0
            ELSE 1
        END
    ) AS DividendRate_Match,
    (
        CASE
            WHEN MD.LocalTaxRate IS NULL OR WD.LocalTaxRate IS NULL THEN NULL
            WHEN MD.LocalTaxRate <> WD.LocalTaxRate THEN 0
            ELSE 1
        END
    ) AS LocalTaxRate_Match
from Entitlement e
left join Entitlement_Data wd on e.id = wd.entitlementID and wd.type = 0
left join Entitlement_Data md on e.id = md.entitlementID and md.type = 1

您可以使用以下方法限制 Entitlement 中在 Entitlement_Data 表中至少有一行的行(不关心是弱还是每月):

where wd.type is not null or md.type is not null

关于sql - 自 FULL OUTER JOIN 的替代方案以获得两个条目之间的匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9308898/

相关文章:

sql-server - 带订单树的递归 SQL 查询

sql - "INNER JOIN"和 "OUTER JOIN"和有什么区别?

.net - 如何用纯 SQL 编写 LINQ 的 .Skip(1000).Take(100) ?

c# - 如何使用 RFID 徽章和 PIN 码安全访问

mysql结果重组结果

mysql - SQL - OUTER JOIN a UNION-ed 表

sql - 在团队中共享常见 SQL 查询

c# - 数据库优先 Entity Framework 将唯一外键映射为一对多

sql - HSQLDB 列出所有约束

mysql - 声明变量MySQL触发器