【问题标题】:CASE vs OR in SQL filtersSQL 过滤器中的 CASE 与 OR
【发布时间】:2020-11-08 13:59:16
【问题描述】:

我正在学习关于 SQL 的 DataCamp 课程。本课程考察European soccer database

课程的一部分讨论了使用CASE 作为过滤器,这样您就不会留下一大堆NULL 值。提供以下代码来专门过滤切尔西的主场和客场胜利:

SELECT date, season,
  CASE WHEN hometeam_id = 8455 AND home_goal > away_goal
            THEN 'Chelsea home win!'
       WHEN awayteam_id = 8455 AND home_goal < away_goal
            THEN 'Chelsea away win!' END AS outcome
FROM match
WHERE CASE WHEN hometeam_id = 8455 AND home_goal > away_goal
                THEN 'Chelsea home win!'
           WHEN awayteam_id = 8455 AND home_goal < away_goal
                THEN 'Chelsea away win!' END IS NOT NULL;

看这段代码,似乎有些多余。例如,过滤器中的CASE 再次定义类别,即使它是在SELECT 子句中完成的。在我看来,在过滤器中简单地使用ANDOR 会更有利:

SELECT date, season,
  CASE WHEN hometeam_id = 8455 AND home_goal > away_goal
            THEN 'Chelsea home win!'
       WHEN awayteam_id = 8455 AND home_goal < away_goal
            THEN 'Chelsea away win!' END AS outcome
FROM match
WHERE (hometeam_id = 8455 AND home_goal > away_goal)
   OR (awayteam_id = 8455 AND home_goal < away_goal);

有几个问题。

  1. 像这样使用CASE 子句有什么特别的原因吗?还是 DataCamp 课程只是以可教的方式在过滤器中使用CASE,而这种特殊情况不一定有实际用途?
  2. 如第一个查询所示,在过滤 CASE 子句中分配类别有什么作用?
  3. 如果我们在CASE 子句上进行过滤,那么为什么不简单地以WHERE outcome IS NOT NULL 结尾呢?

再次,我理解这是否完全只是为了教授一个原则——在这种情况下,第一个问题仍然存在——但假设所有这些冗长背后有更深层次、更复杂的原因,那是什么?

【问题讨论】:

  • where 子句中使用case 是不寻常且不必要的。

标签: sql sqlite filter


【解决方案1】:

你是对的,它应该是你写的where 子句。 where 只需要一个布尔值。

我想不出有人会用它作为教学示例的原因。

这样会更有意义:

WHERE CASE
      WHEN hometeam_id = 8455 AND home_goal > away_goal THEN
        true
      WHEN awayteam_id = 8455 AND home_goal < away_goal THEN
        true
      ELSE
        false
      END

至少没有多余的字符串,else 的情况更明显,但这仍然是编写where 子句的一种非常不寻常的方式。

如果我们在 CASE 子句上进行过滤,那么为什么不简单地以 WHERE 结果 IS NOT NULL 结束?

大多数数据库不支持在 where 子句中使用像 outcome 这样的列别名。 SQLite 可以,但我建议不要习惯非标准功能。

【讨论】:

    【解决方案2】:

    WHERE 子句中,您通常希望避免使用CASE 表达式。原因很简单:CASE 表达式强制执行特定的求值顺序。并且执行评估顺序会影响优化器生成最佳查询计划的能力。

    如果解决方案坚持使用CASE,我会说这是一个非常糟糕的例子。虽然在某些情况下CASE 表达式在WHERE 子句中很有帮助,但您描述的不是其中之一。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-31
      • 1970-01-01
      • 1970-01-01
      • 2022-12-06
      • 2014-12-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多