简体   繁体   中英

Attempting to use result of Case Expression in a join .. need to improve query

I have the following query which allows me to join the TransactionClass tables base on TransactionClassID from either the primary table (Transactions) or TransactionRules based on a condition as below:

SELECT
    Description,
    TC.Name,
    (CASE
         WHEN (TR.TransactionRuleId > 0)
         THEN TR.TransactionRuleId
         ELSE T.TransactionClassId
    END) As ClassId
FROM Transactions AS T
LEFT JOIN TransactionRules TR ON T.Description LIKE TR.Pattern
LEFT JOIN TransactionClasses TC ON TC.TransactionClassId =
                                (CASE
                                    WHEN (TR.TransactionRuleId > 0)
                                    THEN TR.TransactionClassId
                                    ELSE T.TransactionClassId
                                END)

The query is running on SQL Server, In effect, it retrieves the correct TransactionClass entry depending on whether or not the join on TransactionRules was successful or not. The above query works, but I am trying to simplify the query so that I do not have to repeat the CASE expression in two places.

I attempted to capture the result of the case expression in a variable and use that as follows:

SELECT
    Description,
    x
FROM Transactions AS T
LEFT JOIN TransactionRules TR
    ON T.Description LIKE TR.Pattern
LEFT JOIN TransactionClasses TC
    ON TC.TransactionClassId = x
WHERE x = (CASE
               WHEN (TR.TransactionRuleId > 0)
               THEN TR.TransactionRuleId
               ELSE T.TransactionClassId
           END)

But I get the error:

[S0001][207] Line 8: Invalid column name 'x'.

Where am I going wrong in my attempt to have only one CASE Expression?

CROSS APPLY is a tidy way to reuse a calculated value eg

SELECT
    [Description]
    , TC.[Name]
    , Class.Id
FROM Transactions AS T
LEFT JOIN TransactionRules TR ON T.[Description] LIKE TR.Pattern
CROSS APPLY (
    VALUES (
        CASE
           WHEN TR.TransactionRuleId > 0
           THEN TR.TransactionRuleId
           ELSE T.TransactionClassId
        END
    ) 
) AS Class (Id)
LEFT JOIN TransactionClasses TC ON TC.TransactionClassId = Class.Id;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM