探索SQL的WHERE语句

85 阅读6分钟

这篇文章将谈论SQL的WHERE语句。

关系数据库表可能包含数十亿的数据行。在实际情况中,你可能不希望一次处理整个记录集。例如,如果我们有一个记录客户所有订单的表,我们可能不希望显示自该表创建以来应用程序中的所有数据。你可能需要特定订单的数据,特定期限的订单,如季度、年份或特定客户或地区的订单。

结构化查询语言(SQL)使用SQL WHERE条款,根据应用条件进行数据过滤。它通常在选择、更新或删除语句中使用。

让我们继续探讨WHERE子句,它的语法,对单个或多个条件的使用,包括和排除基于查询表达的数据。

SQL哪里子句的介绍

Where子句在SQL语句Select, Update, Delete中有助于过滤满足特定条件的数据。下面的SQL查询检索了存储在[SalesLT].[SalesOrderDetail]表中的所有数据。如下图所示,它检索了540条记录。

  SELECT * FROM SalesLT.SalesOrderDetail

Retrieve records from a table

假设你的客户打电话到客户服务台要求获得一些关于他的订单的信息。如果这个表很庞大,而且你检索了所有的记录来寻找特定的客户订单ID。在这种情况下。

  • 由于记录的数量,查询的执行将需要更长的时间
  • 你的周转时间会比较长,而且由于长时间的等待,你可能无法满足客户的要求。
  • 如果数据集很大,而且没有分类,要寻找一个特定的订单ID是很困难的。

因此,你可以在from子句后添加where子句,并指定条件。查询优化器将只检索满足条件的特定行,并将它们显示给你。

  SELECT * FROM SalesLT.SalesOrderDetail WHERE SalesOrderID=71776

Add a Where clause

让我们从性能的角度来比较这两个查询的执行情况。

  • 查询1在批次中的相对成本为70%,它使用了聚类索引扫描操作符
  • 查询2相对来说比查询便宜(30%的成本),它使用了聚类索引寻址操作符

View Execution plan

如果我们深入研究聚类索引扫描和寻址操作者,我们可以看到在估计的CPU成本、IO成本、读取的行数上的差异。

View execution plan properties
注意:执行计划操作符及其性能取决于各种因素,如索引、统计、查询编写技术。

SQL WHERE语句示例

让我们在本节中探讨SQL WHERE语句的例子。

带有数字比较的SQL WHERE语句

你可以对支持的列类型,如int, bigint,使用带有数字比较的where子句。

  SELECT * FROM SalesLT.SalesOrderDetail WHERE OrderQty=1

注意:你不能对其他数据类型的列使用数字比较,如varchar, nvarchar。

WHERE statement with Numeric comparison

带有字符比较的SQL WHERE语句

默认情况下,SQL Server会执行不区分大小写的搜索。你可以使用字符串等字符从表中过滤记录。例如,下面的查询返回在where子句中指定的具有产品名称的记录。

  SELECT * FROM SalesLT.Product  WHERE name='awc Logo Cap'

statement with Characters comparison

如果我们指定大写或小写的字符串,SQL Server返回类似的结果。

  SELECT * FROM SalesLT.Product  WHERE name='AWC LOGO CAP'

specify strings in the upper case or lower

带有比较运算符的SQL Where语句

SQL Server有各种比较运算符来构建条件并返回满意的查询结果。这些比较运算符如下。

  • 等价运算符(=)
  • 大于(>)和小于(<)
  • 大于或等于(>=)
  • 小于或等于(<=)
  • 不等( <>)

例如,下面的查询在where子句中使用了不等于(<>)操作符,排除了where子句中指定的产品名称。

  SELECT * FROM SalesLT.Product  WHERE name<>'AWC LOGO CAP'

同样的,下面的查询返回所有产品ID大于或等于800的产品。

  SELECT * FROM SalesLT.Product  WHERE ProductID >= 800

带有逻辑运算符的SQL Where语句

SQL Server有逻辑运算符,可以在特定条件下返回真或假的结果。这些逻辑运算符是 AND, OR 和 NOT。

  • AND运算 符 在AND运算符中,所有的表达式都要满足才能得到结果。
  • 该查询返回满足以下条件的记录。
  • 颜色= 红色
  • 名称= Road-150 Red, 44
  SELECT * FROM SalesLT.Product  WHERE color= 'Red' and [Name]='Road-150 Red, 44'

Logical operators

如果任何一个条件没有返回真,查询就不会在输出中得到任何记录。

Invalid conditions

  • OR运算符。如果任一条件满足OR子句,查询就会返回结果。
  • 查询返回满足至少满足以下条件之一的记录。
  • 颜色=蓝色
  • 名称= 路-150 红,44
SELECT * FROM SalesLT.Product  WHERE color= 'Blue' OR 
  [Name]='Road-150 Red, 44'

OR operator

  • 非运算符。Not操作符将条件的结果反转。例如,下面的查询返回具有产品ID 707或708的查询。

Check the results

我们可以使用NOT逻辑运算符从输出中排除产品ID 707或708。

NOT logical operator

使用带有日期的SQL where语句

SQL查询可以使用日期列来过滤记录。这就像字符数据类型和比较运算符的过滤记录。

 SELECT ProductID, Name, SellStartDate FROM SalesLT.Product  
  WHERE SellStartDate>='2005-06-30'

where语句中的函数

你可以在where语句中结合诸如YEAR()、Month()等函数来过滤特定条件下的记录。例如,下面的查询使用year()函数,找到销售开始日期为2005年的记录。

SELECT ProductID, Name, SellStartDate FROM SalesLT.Product  
  WHERE year(SellStartDate)='2005'

SQL where statement with dates

用WHERE语句更新和删除

更新语句也使用where子句来更新特定的行。例如,如果你想更新一个特定产品的成本,你可以在where子句中指定产品ID并更新记录。

注意:where子句是如果你不在更新语句中指定where条件,SQL查询将更新表中的所有记录。

  UPDATE SalesLT.Product  
  SET standardcost=100
  WHERE Productid=710

同样,我们可以在删除语句中指定where子句来删除一个表的特定记录。

  DELETE from  SalesLT.Product WHERE Productid=710

Where 和 Having 子句

有时,你要处理汇总的数据,如平均值、最小值和最大值。你不能用where子句从聚合的数据中过滤记录。因此,在特殊情况下,如GROUP BY, MAX(), MIN(), AVG()函数,我们可以使用HAVING子句来过滤记录。

例如,下面的T-SQL脚本根据产品ID对记录进行分组,并使用AVG()函数计算出大于976的产品ID的平均价格。它使用having子句来过滤聚合数据中的记录。

 SELECT avg(standardcost) as AvgPrice,ProductID FROM SalesLT.Product  
  GROUP BY ProductID
  HAVING  ProductID>976

Where and Having clause

同样,下面的T-SQL脚本计算产品表中976和980之间的产品ID的标准成本之和。

SELECT SUM(standardcost) as SUMPrice,ProductID FROM SalesLT.Product  
  GROUP BY ProductID
  HAVING  ProductID between 976 AND 980

对WHERE语句的有用的考虑

  • 你应该避免从一个大表中选择所有的记录以避免性能问题。使用SQL Where子句来限制输出中的行数是很好的。
  • 你可以对数字、字符数据类型、逻辑、比较运算符使用where子句。
  • 你应该总是使用带有where子句的删除语句。如果你想从一个表中删除所有记录,最好使用TRUNCATE TABLE语句。
  • 你可以在where子句中结合多个条件,并将它们与逻辑运算符相结合。