【问题标题】:Is the result from an 'OR' clause in SQL SELECT defined?是否定义了 SQL SELECT 中的“OR”子句的结果?
【发布时间】:2018-11-29 08:19:21
【问题描述】:

我的意思是:

如果我有如下 SELECT 语句:

SELECT * FROM TAB1 WHERE COL1 = ('VAL1' OR 'VAL2') AND ...

如果有问题的表中同时包含“VAL1”和“VAL2”的条目,WHERE 子句中的顺序有什么不同吗?

如果我希望用“VAL1”取回记录,但如果前者不可用,则取回“VAL2”,上述 SELECT 是否能保证这一点?或者在这种情况下响应未定义?而且这种行为是否可能是特定于供应商的?

【问题讨论】:

  • 您使用的是哪个 dbms?
  • @jarlh 是 SAP HANA。

标签: sql select where-clause hana


【解决方案1】:

不,你不能这样做,它可能会根据位置和顺序返回错误的记录。

试试:

SELECT * FROM TAB1 
WHERE (COL1 = 'VAL1' OR (COL1 = 'VAL2' and (select count(*) from tab1 where COL1 = 
'VAL1') = 0)) AND ...

【讨论】:

  • where (select count(*)) = 0where not exists 差很多。
【解决方案2】:

做一个UNION ALL。让第一个 SELECT 返回 VAL1 行。有另一个 SELECT 返回 VAL2 行,但前提是不存在 VAL1 行。

SELECT * FROM TAB1
WHERE COL1 = 'VAL1'
union all
SELECT * FROM TAB1
WHERE COL1 = 'VAL2'
  and NOT EXISTS (SELECT * FROM TAB1 WHERE COL1 = 'VAL1')

与@Claudio Biselli 的回答基本相同,但更易于优化。

【讨论】:

    【解决方案3】:

    我会选择根据偏好对结果进行排名,然后选择最喜欢的记录如下

    SELECT * FROM (
    SELECT *,ROW_NUMBER() OVER(order by case when col1='VAL1' then 1 
                                             when col1='VAL2' then 2
                                        end asc) as rnk  
      FROM TAB1 
     WHERE COL1 = ('VAL1' OR 'VAL2') 
     )X
    WHERE X.RNK=1
    

    【讨论】:

    • WHERE 子句中的顺序不会产生影响,AFAIK
    【解决方案4】:

    也许使用 IN 而不是 OR

    例如:

    SELECT * FROM TAB1 WHERE COL1 IN ('VAL1','VAL2') AND ...
    

    【讨论】:

    • IN 运算符是多个 OR 条件的简写。
    • 这并没有回答这个问题。结果是否有保证的顺序,它会受到 OR 子句中的顺序的影响吗?
    【解决方案5】:

    WHERE 子句中的所有条件在 SQL 中同时应用。根本没有保证或暗示的顺序。这适用于任何 SQL DBMS,而不仅仅是 SAP HANA。

    要获得加权选择标准,您需要创建一个加权函数,正如其他回复所示。 一种相当容易实现的方法是首先为所有可能的权重创建SELECTs,然后选择权重最高/最低的条目。

    例如:

    WITH weighted AS ( 
     SELECT 100 as SEL_WEIGHT, PK1, PK2 
     FROM TAB1 WHERE COL1 = 'VAL1'
    UNION ALL
     SELECT 60 as SEL_WEIGHT, PK1, PK2 
     FROM TAB1 WHERE COL1 = 'VAL2'
    UNION ALL
     SELECT -1 as SEL_WEIGHT, PK1, PK2 
     FROM TAB1 WHERE COL1 IS NULL)
    
    SELECT 
         * 
    FROM 
        weighted 
    WHERE (PK1, PK2, SEL_WEIGHT) in
          (SELECT PK1, PK2, MAX(SEL_WEIGHT) as MAX_WEIGHT
           FROM weighted
           GROUP BY PK1, PK2);
    

    在此示例中,子选择查找最大权重和相关的主键列(PK1PK2)并将它们作为最终选择标准加入主SELECTCOL1 ='VAL1' 的记录权重最高 (100),并且优先于 COL1='VAL2' (60) 或 COL1NULL (-1) 的记录。

    这种结构的好处是很容易看出权重是如何定义的,并且每个权重都可以有自己独立的条件组合。

    由于加权选择标准在 SQL 系统中是非标准的,我强烈建议使实现尽可能明显,以避免以后出现混淆和误解。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-22
      相关资源
      最近更新 更多