3、ving_condition>(10)orderby其中,每个关键字都是一个独立的逻辑处理步骤,而关键字之前的数字代表了它在查询语句中的逻辑处理顺序。SQL和其他编程语言最显著的不同之处就是代码处理的顺序。对于大多数编程语言,代码的书写顺序就是它的处理顺序。对于SQL,第一个处理的子句是from子句,而select子句,虽然是第一个出现的,但几乎是最后一个处理的。每个步骤生成的一个虚拟表会作为下一个步骤的输入。这些虚拟表对调用者(客户端应用程序或外部查询)来说是不可见的。返回给调用者的,只是最后一个步骤生成的表。如果某个子句不在查询里,那么相应的步骤就
4、会直接被跳过。基于客户/订单情景的样例查询为了详细描述逻辑处理的各阶段,我们一起来完成一个样例查询。首先,运行以下脚本来创建表Customers和Orders,并写入样例数据。usetempdbifobject_id('Customers','U')isnotnullbegindroptableCustomersendifobject_id('Orders','U')isnotnullbegindroptableOrdersendGocreatetableCustomers(customer_idint,namechar(20),genderchar(1))insertCustom
5、ersselect1,'AmitPaul','M'insertCustomersselect2,'DhaniLennevald','M'insertCustomersselect3,'MarieFredriksson','F'insertCustomersselect4,'PerGessle','M'createtableOrders(order_idint,customer_idint,product_idchar(10))insertOrdersselect1,3,'B000XGJH1O'insertOrdersselect2,2,'B000GP8448'insertOrder
6、sselect3,2,'B000FPOJOS'insertOrdersselect4,1,'B000FQ2D5E'insertOrdersselect5,3,'B000G0HJ3K'insertOrdersselect6,2,'B0011WMIME'insertOrdersselect7,1,'B000IONGWM'select*fromCustomersselect*fromOrders查询语句的要求是返回订单总数不超过2的男性客户的客户编号、姓名及订单总数,并按照订单总数升序排序。selectc.customer_id,min(c.name)asname,count(o.ord
7、er_id)asorder_countfromCustomersascleftouterjoinOrdersasoonc.customer_id=o.customer_idwherec.gender='M'groupbyc.customer_idhavingcount(o.order_id)<=2orderbyorder_count步骤1:生成笛卡尔积(CROSSJOIN)笛卡尔积是在from子句中出现的头两个表之间进行的,结果便是生成了虚拟表VT1。VT1包含了左表中每一行和右表中每一行的所有可能的组合(左表就是查询语句中出现在join关键字之前的表)。如果左表有n行,右表有m行
8、,VT1就有n×m行。VT1中的字段是由源表的名称限定的(作前缀的),如果查询中指定了表的别名,这个前缀也可以使用别名。在随后的步骤中(步骤2以及后面的步骤),如果对某个字段名的引用是有歧义的(字段名出现在多个输入表中),那么该字段名必须是表限定的(比如,c.customer_id)。对于只出现在一个输入表中的字段名,指定表限定符是可选的(比如,o.order_id或order_id)。selectc.customer_idas[c.customer_id],c.na