如何为 SQL“质量检查”规则添加例外?

问题描述 投票:0回答:1

我有以下问题:

SELECT A.ID, A.FUND, B.MANAGER_NAME, C.FUND, C.MGR_NM
FROM TABLE_1 A 
LEFT JOIN TABLE_2 B ON  
            A.ID = B.ID
LEFT JOIN REFERENCE_TABLE C ON
A.FUND = C.FUND
WHERE 
B.MANAGER_NAME != C.MGR_NM

此查询的结果显示经理何时被错误地分配给基金。

REFERENCE_TABLE
是真理的来源,并显示正确的
FUND
MGR_NM
作业。但是,我需要为这条规则添加一个例外:当
FUND = 'BOSTON'
时,如果
MANAGER_NAME
= 'Kim, John, or Danny' 就可以了。

所有其他基金在基金和经理姓名之间具有 1:1 的关系。
如何将此异常添加到我的查询中?

sql where-clause
1个回答
1
投票

Show all results where

MANAGER_NAME
does not match
MGR_NM
, unless the
FUND
is 'BOSTON', then it is okay if
MANAGER_NAME
is one of the 'Kim, John, or Danny'

听起来像是在您的标准中使用简单的

OR
表达式的情况,但我们需要反转“Kim、John 或 Danny”的匹配项,如果基金是“BOSTON”并且
MANAGER_NAME
不是其中之一,则返回“金、约翰或丹尼”

但这并不太简单,但是在将

OR
运算符注入您的条件时要小心,如果您没有使用括号来分隔条件中的逻辑表达式,那么
OR
将独立比较运算符的任一侧,这可能会产生不良结果结果。

在下面的解决方案中没有使用括号,但我们必须在原始逻辑中评估

BOSTON
基金的不匹配,以便'Kim','John','Danny'被认为对其他基金无效:

SELECT A.ID, A.FUND, B.MANAGER_NAME, C.FUND, C.MGR_NM
FROM TABLE_1 A 
LEFT JOIN TABLE_2 B ON A.ID = B.ID
LEFT JOIN REFERENCE_TABLE C ON A.FUND = C.FUND
WHERE 
A.FUND <> 'BOSTON' 
AND B.MANAGER_NAME != C.MGR_NM
OR A.FUND = 'BOSTON' 
   AND B.MANAGER_NAME != C.MGR_NM 
   AND B.MANAGER_NAME NOT IN ('Kim', 'John', 'Danny')

您可能更喜欢使用方括号使表达式更具可读性,或突出显示特殊情况。无论如何,RDBMS 可能会扩展评估的括号,因此它不会对性能产生任何影响,但它确实允许我们使用这样的语法,如果它有帮助的话:

SELECT A.ID, A.FUND, B.MANAGER_NAME, C.FUND, C.MGR_NM
FROM TABLE_1 A 
LEFT JOIN TABLE_2 B ON A.ID = B.ID
LEFT JOIN REFERENCE_TABLE C ON A.FUND = C.FUND
WHERE 
B.MANAGER_NAME != C.MGR_NM
AND (
    A.FUND <> 'BOSTON' 
    OR A.FUND = 'BOSTON' 
       AND B.MANAGER_NAME NOT IN ('Kim', 'John', 'Danny')
    )

虽然这应该可行,但问题是为什么“Kim”、“John”、“Danny”有效?如果

REFERENCE_TABLE
是真实来源,那么您可以允许此表中每个基金的多个条目,那么您根本不需要硬编码 'BOSTON' 的具体情况,我们可以使用
OUTER JOIN
只返回不相关的行:

SELECT A.ID, A.FUND, B.MANAGER_NAME, C.FUND, C.MGR_NM
FROM TABLE_1 A 
LEFT JOIN TABLE_2 B ON A.ID = B.ID
LEFT OUTER JOIN REFERENCE_TABLE C ON A.FUND = C.FUND 
                                  AND B.MANAGER_NAME = C.MGR_NM
WHERE 
C.FUND IS NULL

这是可行的,因为所有有效的管理器都将匹配,并且

C.FUND
将具有非空值。然而,所有在
REFERENCE_TABLE
中找不到相应匹配项的行对于
null
的值为
C.FUND
,这些是我们想要看到的行。

© www.soinside.com 2019 - 2024. All rights reserved.