- 类别:
WHERE¶
WHERE 子句指定了一个充当筛选器的条件。您可以使用 WHERE 子句执行以下操作:
语法¶
参数¶
使用说明¶
WHERE 子句中的谓词表现得就像是在 FROM 子句之后计算的一样(尽管优化器可以在不影响结果的情况下对谓词进行重新排序)。例如,如果 WHERE 子句中的谓词引用了参与 FROM 子句外部联接的表的列,则筛选器将对联接返回的行(可能用 NULLs 填充)进行操作。
创建可能计算 NULLs 的表达式时要小心。
在大多数上下文中,布尔表达式
NULL = NULL返回 NULL,而不是 TRUE。考虑使用 IS [ NOT ] NULL 来比较 NULL 值。In a
WHEREclause, if an expression evaluates to NULL, the row for that expression is removed from the result set (that is, it is filtered out).
The maximum number of expressions in a list is 200,000. For example, the limit applies to the number of expressions in the following SELECT statement:
To avoid reaching the limit, perform a join with a lookup table that contains the expression values, rather than specifying the values using the IN clause. For example, when the expression values in the previous example are added to a lookup table named
mylookuptable, you can run the following query successfully even if the lookup table has more than 200,000 rows:
WHERE 子句中的联接¶
虽然 WHERE 子句主要用于筛选,但是 WHERE 子句也可以用于表示多种类型的联接。有关联接的概念信息,请参阅 使用联接。
WHERE 子句可以通过包含联接条件来指定联接,联接条件是布尔表达式,用于定义 JOIN 一端的哪些行与联接另一端的哪些行相匹配。
以下两个等效查询显示了如何在 WHERE 或 FROM 子句中表达内部联接:
可以通过在 WHERE 子句中使用 (+) 语法或在 FROM 子句中使用 OUTER JOIN 关键字来指定外部联接。
当您用 (+) 指定外部联接时, WHERE 子句将 (+) 应用于表的每个“内部”联接列(定义如下)。
备注
外部联接的结果包含一个表中所有行的副本。在本主题中,保留行的表称为“外部”表,另一个表称为“内部”表。
在 LEFT OUTER JOIN 中,左边的表是外部表,右边的表是内部表。
在 RIGHT OUTER JOIN 中,右边的表是外部表,左边的表是内部表。
以下查询显示等效的左外部联接,其中一个指定 FROM 子句中的联接,另一个指定 WHERE 子句中的联接:
在第二个查询中, (+) 位于右侧,用于标识内部表。
这两个查询的输出示例如下:
如果要在多个列上联接一个表,请在内部表的 每个 列上使用 (+) 符号(以下示例中的 t2 ):
备注
(+)符号的出现位置有许多限制; FROM 子句外部联接更具表现力。Snowflake 建议只有在移植已经使用了符号(+)的代码时才使用该符号。新代码应避免使用这种符号。限制包括:
不能使用
(+)符号创建FULL OUTER JOIN;只能创建LEFT OUTER JOIN和RIGHT OUTER JOIN。以下内容 无 效。该语句会导致以下错误消息:SQL compilation error: Outer join predicates form a cycle between 'T1' and 'T2'.如果一个表参与一个查询中的多个联接,则
(+)符号只能将该表指定为其中 一个 联接中的内部表。以下内容 无 效,因为t1在两个联接中充当内部表。该语句会导致以下错误消息:SQL compilation error: Table 'T1' is outer joined to multiple tables: 'T3' and 'T2'.但是请注意,您可以使用
(+)将 不同的表 标识为同一 SQL 语句中 不同联接 的内部表。以下示例联接三个表:t1、t2和t3,其中两个是内部表(在不同的联接中)。此语句执行以下操作:
t1和t2之间的 LEFT OUTER JOIN(其中t2是内部表)。
t2和t3之间的 LEFT OUTER JOIN(其中t3是内部表)。
(+) 可以紧邻表名和列名,也可以用空格分隔。以下两项均有效:
查询可以包含在 FROM ... ON ... 子句和 WHERE 子句中指定的联接。但是,在同一查询的不同子句中指定联接会使该查询更难读取。
WHERE 子句中对联接的支持主要是为了向后兼容不使用 FROM ... ON ... 语法的旧查询。Snowflake 建议在编写带有联接的新查询时使用 FROM ... ON ...。有关详细信息,请参阅 JOIN。
示例¶
筛选的简单示例¶
以下显示了 WHERE 子句的一些简单用法:
此示例使用子查询,显示所有账单金额小于平均水平的发票:
在 WHERE 子句中执行联接¶
要在 WHERE 子句中指定联接,请在 FROM clause 中列出要联接的表,用逗号分隔这些表。在 WHERE 子句中将联接条件指定为筛选器,如下例所示:
备注
逗号运算符是 INNER JOIN 的旧语法。以下语句显示了使用较新语法执行联接的推荐方法。下面的查询等同于上面的查询:
下一节将展示 3 表联接,并展示 0、1 或 2 (+) 外部联接运算符的行为差异。
在执行查询之前,创建并加载要在联接中使用的表:
执行 3 向内部联接。这不使用
(+)(或 OUTER 关键字),因此是一个内部联接。输出仅包括有部门、项目和员工的行:执行外部联接。除了 使用
(+)使第二个联接成为右外部联接之外,这与前面的语句类似。其效果是,如果某个部门包含在输出中,则该部门的所有项目都将包括在内,即使这些项目没有员工:执行两个外部联接。这与前面的语句相同, 只是 它使用
(+)将两个联接都变成外部联接。结果是所有部门都包括在内(即使他们还没有项目或员工),所有与部门相关的项目都包括在内(即使他们还没有员工)。请注意,输出不包括没有部门的项目。
(但是,请记住,Snowflake 建议在 FROM 子句中使用 OUTER 关键字,而不是在 WHERE 子句中使用 (+) 运算符。)