插入dbo.Orders(订单ID,客户ID)值(6,“ MRPHS”);
将INSERT插入dbo.Orders(订单ID,客户ID)值(7,NULL);
执行结果:


3. 查询语句
使用tempdb;
GO
选择C.customerid,COUNT(O.orderid)个数字
FROM dbo.Customers AS C
左外联接dbo. 按AS O订单
ON C.customerid = O.customerid
C.city ='马德里'
按C.customerid分组
有COUNT个(O.orderid)<3
按编号排序;
执行结果:

4. 逻辑查询处理步骤的详细说明
1. 进行笛卡尔积乘以形成VT1. 如果左表包含n行,右表包含m行,则VT1将包含n×m行.
执行结果VT1:

2. 应用ON过滤器,VT2中仅包含
ON C.customerid = O.customerid
三值逻辑:
TRUE,FALSE,UNKNOWN是SQL中逻辑表达式的可能值.
UNKNOWN值通常出现在包含NULL值的逻辑表达式中,例如NULL> 42; NULL = NULL; X + NULL> Y.
NOT TRUE等于FALSE
NOT FALSE等于TRUE
NOT UNKNOWN等于UNKNOWN
所有查询过滤器,例如ON,WHERE和HAVING都将UNKNOWN视为FALSE.

CHECK约束中的UNKNOWN值被视为TRUE. 如果表包含CHECK约束,要求薪水列的值必须大于0,则可以接受插入薪水为NULL的行.
UNIQUE约束,排序操作和分组操作将两个NULL值视为相等. 例如,如果表中的一列定义了UNIQUE约束,则不能在该列中插入两行带有NULL的行. GROUP BY子句将所有NULL值分成一组. ORDERB BY子句将所有NULL值排在一起.
向VT1 VT2添加ON过滤器的结果:

3. 添加一个外部行. 通过指定LEFT,RIGHT和FULL的OUTER JOIN,可以将左表,右表和所有表标记为保留表. 将表设置为保留表意味着即使

4. 应用WHERE筛选器,只有与
对于包含OUTER JOIN子句的查询,如何确定是在ON过滤器中还是在WHERE过滤器中指定了逻辑表达式: 在添加外部行之前应用ON,在添加外部行之后应用WHERE. ON过滤器不是保留表中某些行的最终方法,因为还执行添加外部行的步骤,并且WHERE过滤器去除这些行也是最终的.
仅当使用外部联接时,ON和WHERE子句将具有此逻辑限制. 使用内部联接时,指定逻辑表达式的位置无关紧要,因为上面没有步骤3.
C.city ='马德里'
生成虚拟表VT4:

5. 分组. GROUP BY子句中列列表的每个唯一值都组合到一个组中以生成VT5:
组
C.customerid

FISSA
FRNDO
KRLOS
VT5由两部分组成: 组部分和原始部分.
如果在查询中指定了GROUP BY子句,则所有后续步骤(例如HAVING,SELECT)只能指定可从标量值组获得的表达式. 换句话说,表达式的结果是GROUP BY列表中的列/表达式(例如: C.customer)或聚合函数(例如: COUNT(O.orderid)). 此限制是因为最终结果集每个组最多包含一行.
在此阶段,两个NULL被视为相等. 所有NULL值都将分配给一个组.
如果指定了GROUP BY ALL,则在WHERE过滤器中删除的组将被添加到VT5,并且原始零件为空集. 在以下步骤中,将COUNT聚合函数应用于此组的结果将为0,而应用其他聚合函数的结果将为NULL. 最好不要使用GROUP BY ALL.
6. 使用CUBE或ROLLUP选项创建超组并将其添加到上一步返回的虚拟表中以生成VT6.
7. 应用HAVING过滤器后,只有与
有COUNT个(O.orderid)<3
在这里使用
Count(O.orderid)而不是COUNT(*),因此外部行不计入COUNT,因为O.orderid为NULL. 例如,FISSA组的COUNT(O.orderid)为0.
红色部分是通过HAVING过滤的组.
组
C.customerid

FISSA
FRNDO
8. 处理SELECT列表,并将别名应用于不是基础列的表达式,以便它们在结果表中具有名称. 在SELECT列表中创建的别名不能在前面的步骤中使用,甚至不能在SELECT列表中使用,只能在ORDER BY中使用.
选择C.customerid,COUNT(O.orderid)个数字
生成VT8:

从逻辑上讲,应该假定所有操作都同时发生.
9. 应用DISTINCT子句. 如果在查询中指定了DISTINCT子句,则将从上一步返回的虚拟表中删除重复的行,并生成虚拟表VT9. 使用GROUP BY,然后使用DISTINCT是多余的.
10. 应用ORDER BY子句以根据ORDER BY子句中的列列表对上一步中返回的行进行排序,然后返回游标VC10. 仅此步骤可以使用SELECT别名. 如果指定了DISTINCT,则ORDER BY子句中的表达式只能访问上一步返回的虚拟表,并且只能按已选择的列进行排序.
Order BY支持在ANSI SQL 1999中得到了增强,允许在SELECT阶段访问输入和输出虚拟表. 也就是说,如果未指定DISTINCT,则可以在ORDER BY子句中指定可以在SELECT子句中使用的任何表达式,并且可以按最终结果集中不存在的表达式进行排序.
按编号排序;
您还可以在ORDER BY子句的SELECT列表中指定结果列的序列号:
ORDER BY 2,1;
但是请不要这样做,因为您可能会更改SELECT列表,但忘记修改ORDER BY列表,并且当SELECT列表很长时,这不是检查序列号的好方法.
因为此步骤不返回表,而是返回游标,所以不能将使用ORDER BY子句的查询用作表表达式. 表表达式包括: 视图,内联表值函数,子查询,派生表和公用表表达式(CTE).
不假定表中各行的顺序. 除非您确实需要有序的行,否则不要指定ORDER BY子句. 排序是有代价的. SQL Server需要执行有序的索引扫描或使用排序运算符.
在ORDER BY步骤中,两个NULL相等,并且所有NULL都将排列在一起. ANSI没有指定NULL是高于还是低于已知值,而是将这个问题留给特定的实现. -SQL中的NULL等级低于已知值.
按编号排序
光标VC10返回:

11. 应用TOP选项,从游标的前面选择指定的行数,生成表VT11并返回到调用方. 在SQLServer 2000中,TOP的输入必须为常量,在2005年可以为任何独立的表达式.
如果没有ORDER BY子句或WITH TIES选项,则返回的行恰好是第一个物理访问的行,可能会产生不同的结果.
仅当指定了TOP选项时,才能在表表达式中使用带有ORDER BY子句的查询:
选择*
从(选择前100%的订单ID,客户ID
从dbo.Orders
ORDER BY orderid)AS D;
原文:
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/ruanjian/article-187394-2.html
中国军方的处置还是得当的
让人匪夷所思