Question

in my db model I have two entities: Entitlement and Entitlement_Data. Each Entitlement is identified by an incrementing ID (IDENTITY), and can have multiple Entitlement_Data entries, each with a different Type - wich can be either 0 (Weekly) or 1 (Monthly) (EntitlementID and Type are PK for Entitlement_Data, EntitlementID being FK to Entitlement table). For each Entitlement, I need to:

  1. Get the first non-NULL value from either Monthly (Type=1) or Weekly (Type=0) Entitlement_Data, for a given set of Entitlement_Data attributes (SharesPaid, LocalTaxRate, etc...) - the first part of the SELECT;
  2. Get some indication about match/mismatch between Monthly and Weekly Entitlement_Data entries (SharesPaid_Match, etc...) - the last part of the SELECT.

This is the query I'm using 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

Is there a way to avoid FULL OUTER JOIN and obtain the informations I need? I evaluated the use of a GROUP BY but I don't seem to get the results I need. Thank you.

Was it helpful?

Solution

Why don't you left join to "main table" which is Entitlement like in following code:

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

You might limit to rows in Entitlement that have at last one row in Entitlement_Data table (without caring whether is weakly or monthly) using:

where wd.type is not null or md.type is not null
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top