SQL 问题 - 我的 WHERE 子句有什么问题

SQL Question - What is wrong with my WHERE clause

提问人:C Mickley 提问时间:2/6/2021 最后编辑:Adrian MoleC Mickley 更新时间:2/6/2021 访问量:82

问:

自从我不得不使用 SQL 和编写查询以来已经有几年了,但我得到了我意想不到的结果。我花了很多时间查看它,我确信我遗漏了一些明显的东西,但是,当我在下面运行它时,我的查询返回的值不是我的语句中的值。RateCodeWHERE

我做错了什么?我觉得这是一个足够基本的查询(我开始恐慌,因为我失去了技能)

SELECT
    cs.Acct AS Site,
    cs.Addr1 AS Address,
    cs.City,
    cs.State,
    m.TypeDescr AS Service,
    se.Quantity,
    se.SvcCode,
    se.SvcDescr,
    sf.FreqDescr AS Frequency,
    se.SvcId, 
    se.StartDate,
    se.EndDate,
    sr.ReasonDescr AS Reason,
    svr.RateCode,  
    svr.StartDate AS RateStartDate,
    svr.EndDate AS RateEndDate

FROM
    wiSvcEquipment AS se
    LEFT JOIN wiCustSite    AS cs  ON cs.SiteId    = se.SiteId
    LEFT JOIN wiMaterial    AS m   ON m.MatSubType = se.MatSubType
    LEFT JOIN wiSvcReason   AS sr  ON sr.ReasonID  = se.ReasonID
    LEFT JOIN wiSvcVendRate AS svr ON svr.SvcId    = se.SvcID
    LEFT JOIN wiSvcCustRate as scr ON scr.RateCode = se.RateCode
    LEFT JOIN wiSvcFreq     AS sf  ON sf.FreqID    = se.FreqID

WHERE
    se.CustId = ‘013714’
    OR
    se.CustId = ‘014831’
    AND 
    svr.RateCode IN (
        ‘CHGCMBHAUL’, ‘CHGHAUFLAT’, ‘CHGHAUL2’, ‘CHGHAUL3’,
        ‘CHGHAULCOM’, ‘CHGHAULFE’, ‘CHGHAULING’, ‘CHGHAULMIN’,
        ‘CHGVCMBHAU’, ‘CHGVHAUFLT’, ‘CHGVHAULFE’, ‘CHGVHAULNG’,
        ‘CHGWKDHAUL’, ‘CLIHAUFLAT’, ‘CLIHAULFE’, ‘CLIHAULING’
    ) ;
SQL 布尔代数

评论

0赞 Dai 2/6/2021
我假设这些字符是因为您使用的是 Mac,并且您的实际 SQL 具有正常的 ASCII 单引号?'
0赞 Noel 2/6/2021
您的任何连接字段是否为空?这可能会给你带来无效的结果
2赞 Dai 2/6/2021
无论如何,您可能有优先权和困惑。最好在括号中使用显式组(我已经手动编写查询 SQL 超过 17 年了,但我仍然不知道哪些逻辑运算符具有更高的优先级)ANDOR
1赞 Dai 2/6/2021
@Noel 联接值如何导致“无效”结果?这些是对非复合外键的操作 - 对我来说看起来不错。NULLLEFT OUTER JOIN
0赞 Dai 2/6/2021
刚刚检查了 SQL 规范,显然比 .所以这就是你的问题。ANDOR

答:

2赞 Dai 2/6/2021 #1

将 your 更改为用于两列:WHEREIN

WHERE
    se.CustId IN ( '013714', '014831' )
    AND 
    svr.RateCode IN (
        'CHGCMBHAUL', 'CHGHAUFLAT', 'CHGHAUL2', 'CHGHAUL3',
        'CHGHAULCOM', 'CHGHAULFE', 'CHGHAULING', 'CHGHAULMIN',
        'CHGVCMBHAU', 'CHGVHAUFLT', 'CHGVHAULFE', 'CHGVHAULNG',
        'CHGWKDHAUL', 'CLIHAUFLAT', 'CLIHAULFE', 'CLIHAULING'
    );

或者使用显式逻辑组:

WHERE
    (
        se.CustId = '013714'
        OR
        se.CustId = '014831'
    )
    AND 
    svr.RateCode IN (
        'CHGCMBHAUL', 'CHGHAUFLAT', 'CHGHAUL2', 'CHGHAUL3',
        'CHGHAULCOM', 'CHGHAULFE', 'CHGHAULING', 'CHGHAULMIN',
        'CHGVCMBHAU', 'CHGVHAUFLT', 'CHGVHAULFE', 'CHGVHAULNG',
        'CHGWKDHAUL', 'CLIHAUFLAT', 'CLIHAULFE', 'CLIHAULING'
    );

上面的两个子句是完全相同的:在SQL中,运算符只是一系列比较的句法糖。x IN ( a, b, c )( x = a OR x = b OR x = c )

1赞 Z . 2/6/2021 #2

你是说

(se.CustId = ‘013714’ OR se.CustId = ‘014831’)

AND 优先于 OR

1赞 Gordon Linoff 2/6/2021 #3

我可以看到三件事:

  1. 对于第一个条件,你需要括号,或者更好的是。IN
  2. 一系列 S 中除第一个表外的所有条件都应在子句中。LEFT JOINON
  3. 您的字符串有智能引号,但它们应该是“直”单引号。

所以:

SELECT . . .
FROM wiSvcEquipment se
     wiCustSite cs 
     ON cs.SiteId = se.SiteId LEFT JOIN
     wiMaterial m  
     ON m.MatSubType = se.MatSubType LEFT JOIN
     wiSvcReason sr 
     ON sr.ReasonID = se.ReasonID AND
            svr.RateCode IN ('CHGCMBHAUL', 'CHGHAUFLAT', 'CHGHAUL2', 'CHGHAUL3',
                             'CHGHAULCOM', 'CHGHAULFE', 'CHGHAULING', 'CHGHAULMIN’,
                             'CHGVCMBHAU', 'CHGVHAUFLT', 'CHGVHAULFE', 'CHGVHAULNG',
                             'CHGWKDHAUL', 'CLIHAUFLA’, 'CLIHAULFE', 'CLIHAULING'
                            ) LEFT JOIN

        LEFT JOIN
     wiSvcVendRate svr
     ON svr.SvcId = se.SvcID LEFT JOIN
     wiSvcCustRate scr
     ON scr.RateCode = se.RateCode LEFT JOIN
     wiSvcFreq sf 
     ON sf.FreqID = se.FreqID
WHERE se.CustId IN ('013714', '014831')

评论

0赞 Dai 2/6/2021
与原始引擎相比,任何称职的 SQL 引擎都不会为此查询生成相同的执行计划吗?也就是说,如果引擎可以证明它们是等价的,那么谓词可以位于任何一个中,并且仍然具有相同的计划?JOIN x ON yWHERE y
0赞 Gordon Linoff 2/6/2021
@Dai . . .这与查询的语义有关,与语法无关。逻辑是不同的。后续表上的子句将联接更改为内部联接。WHERE
0赞 Kazi Mohammad Ali Nur Romel 2/6/2021 #4

如果 se.CustId = '013714' 子句满足,则无论 retcode 是什么,此查询都将返回行。

您是否打算使用以下条件:

WHERE
    (se.CustId = ‘013714’
    OR
    se.CustId = ‘014831’)
    AND 
    svr.RateCode IN (
        ‘CHGCMBHAUL’, ‘CHGHAUFLAT’, ‘CHGHAUL2’, ‘CHGHAUL3’,
        ‘CHGHAULCOM’, ‘CHGHAULFE’, ‘CHGHAULING’, ‘CHGHAULMIN’,
        ‘CHGVCMBHAU’, ‘CHGVHAUFLT’, ‘CHGVHAULFE’, ‘CHGVHAULNG’,
        ‘CHGWKDHAUL’, ‘CLIHAUFLAT’, ‘CLIHAULFE’, ‘CLIHAULING’
    ) ;