关于SQLServer2005的学习笔记——SQL查询解析步骤

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介:
最近一来因工作上的事情比较闹心,没心事再研究 SQLServer2005 的体系结构;一来关于体系结构确实过于复杂,远远不如应用来的直接明了,所以暂时搁笔。
出于工作上的需要,对应用开发需要更多的了解,所以把心事暂时放到这方面。
 
先从最简单的 SQL 入手来分析一下 SQL 的执行步骤,为什么了解执行步骤,其实与 JOIN 后的 ON 条件和 WHERE 条件容易混淆有关系。
是先执行 ON 还是先执行 WHERE ,很大程度上会决定 SQL 的结果集正确与否。
CREATE TABLE Customers
(
  CustomerID  CHAR(5)     NOT NULL PRIMARY KEY,
  City        VARCHAR(10) NOT NULL
);
CREATE TABLE Orders
(
  OrderID     INT     NOT NULL PRIMARY KEY,
  CustomerID  CHAR(5) NULL REFERENCES Customers(CustomerID)
);
 
INSERT INTO Customers VALUES('FISSA','Madrid');
INSERT INTO Customers VALUES('FRNDO','Madrid');
INSERT INTO Customers VALUES('KRLOS','Madrid');
INSERT INTO Customers VALUES('MRPHS','Zion');
INSERT INTO Orders VALUES(1,'FRNDO');
INSERT INTO Orders VALUES(2,'FRNDO');
INSERT INTO Orders VALUES(3,'KRLOS');
INSERT INTO Orders VALUES(4,'KRLOS');
INSERT INTO Orders VALUES(5,'KRLOS');
INSERT INTO Orders VALUES(6,'MRPHS');
INSERT INTO Orders VALUES(7,NULL); 
 
 
试看看以上两个语句有什么不同,你就会发现很有趣的现象。
SELECT C.CustomerID,COUNT(O.OrderID) AS NumOrders
  FROM Customers C
  LEFT OUTER JOIN Orders O
    ON C.CustomerID=O.CustomerID
  WHERE C.City='Madrid'
  GROUP BY C.CustomerID
  HAVING COUNT(O.OrderID)<3
  ORDER BY NumOrders;
 
SELECT C.CustomerID,COUNT(O.OrderID) AS NumOrders
  FROM Customers C
  LEFT OUTER JOIN Orders O
    ON C.CustomerID=O.CustomerID
    AND C.City='Madrid'
  GROUP BY C.CustomerID
  HAVING COUNT(O.OrderID)<3
  ORDER BY NumOrders; 
 
 
--Step1 ,首先对 FROM 后面的表进行笛卡尔乘积,生成虚表 STEP1
WITH STEP1
AS
(
SELECT C.CustomerID C_CustomerID,C.City C_City,O.OrderID O_OrderID,O.CustomerID O_CustomerID
  FROM Customers C,Orders O
)
SELECT * FROM STEP1 
 
 
--Step2 ,再次应用 ON 语句中的条件,如果没有外关联的话,这里的 ON 和 WHERE 实际上是没有什么差别的,生成虚表 STEP2
WITH STEP2
AS
(
SELECT C.CustomerID C_CustomerID,C.City C_City,O.OrderID O_OrderID,O.CustomerID O_CustomerID
  FROM Customers C
  JOIN Orders O
    ON C.CustomerID=O.CustomerID
)
SELECT * FROM STEP2 
 
 
--Step3 ,如果指定了 OUTER JOIN , SQL 会自动把 STEP2 表中未匹配的行作为外部行添加到 STEP3 中,此处找到了 CustomerID=FISSA,City=Madrid ,这个没有订单但又有相关名字的用户
WITH STEP3
AS
(
SELECT C.CustomerID C_CustomerID,C.City C_City,O.OrderID O_OrderID,O.CustomerID O_CustomerID
  FROM Customers C
  LEFT OUTER JOIN Orders O
    ON C.CustomerID=O.CustomerID
)
SELECT * FROM STEP3 
 
 
--Step4 ,应用 WHERE 条件,过滤不符合条件的记录
AS
(
SELECT C.CustomerID C_CustomerID,C.City C_City,O.OrderID O_OrderID,O.CustomerID O_CustomerID
  FROM Customers C
  LEFT OUTER JOIN Orders O
    ON C.CustomerID=O.CustomerID
  WHERE C.City='Madrid'
)
SELECT * FROM STEP4 
 
 
--Step5 ,对以上的结果集进行分组
WITH STEP5
AS
(
SELECT C.CustomerID,COUNT(O.OrderID) AS NumOrders
  FROM Customers C
  LEFT OUTER JOIN Orders O
    ON C.CustomerID=O.CustomerID
  WHERE C.City='Madrid'
  GROUP BY C.CustomerID
)
SELECT * FROM STEP5 
 
 
--Step6 ,处理 CUBE 、 ROLLUP 之类的语句,此处无此需求
SELECT * FROM STEP6 
 
 
--Step7 处理 Having 筛选器,与 WHERE 条件有些类似
WITH STEP7
AS
(
SELECT C.CustomerID,COUNT(O.OrderID) AS NumOrders
  FROM Customers C
  LEFT OUTER JOIN Orders O
    ON C.CustomerID=O.CustomerID
  WHERE C.City='Madrid'
  GROUP BY C.CustomerID
  HAVING COUNT(O.OrderID)<3
)
SELECT * FROM STEP7 
 
 
--Step8 ,处理 SELECT 列表,即别名转换把 COUNT(O.OrderID) 转换成 NumOrders
SELECT * FROM STEP8 
 
 
--Step9 ,应用 DISTINCT 语句,此处无此需求
SELECT * FROM STEP9 
 
 
--Step10 ,应用 ORDER BY 语句进行排序
SELECT C.CustomerID,COUNT(O.OrderID) AS NumOrders
  FROM Customers C
  LEFT OUTER JOIN Orders O
    ON C.CustomerID=O.CustomerID
  WHERE C.City='Madrid'
  GROUP BY C.CustomerID
  HAVING COUNT(O.OrderID)<3
  ORDER BY NumOrders 
 
 
--Step11 ,执行 TOP 选项,此处无此需求
SELECT * FROM STEP11 
 




本文转自baoqiangwang51CTO博客,原文链接:http://blog.51cto.com/baoqiangwang/310463 ,如需转载请自行联系原作者
相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
相关文章
|
5天前
|
SQL 存储 程序员
SQL查询的一些基本知识和学习指导
【6月更文挑战第17天】SQL查询核心包括基础选择、连接(JOIN)、子查询、聚合函数与GROUP BY、模糊匹配(LIKE)、分页与排序。JOIN操作连接多表,GROUP BY配合聚合函数做统计,LIKE用于模糊搜索。理解存储过程、触发器及自动增长列等进阶概念,通过实践提升SQL技能。
28 2
|
10天前
|
SQL 存储 安全
SQL入门与进阶:数据库查询与管理的实用指南
一、引言 在数字化时代,数据库已经成为各行各业存储、管理和分析数据的关键基础设施
|
12天前
|
SQL 弹性计算 分布式计算
实时数仓 Hologres操作报错合集之在执行SQL查询时遇到了问题,报错原因是“Invalid index column id: 2”,该怎么处理
在使用阿里云实时数仓Hologres时,可能会遇到不同类型的错误。例如:1.内存超限错误、2.字符串缓冲区扩大错误、3.分区导入错误、4.外部表访问错误、5.服务未开通或权限问题、6.数据类型范围错误,下面是一些常见错误案例及可能的原因与解决策略的概览。
|
14天前
|
SQL 流计算
Flink(十三)【Flink SQL(上)SqlClient、DDL、查询】(4)
Flink(十三)【Flink SQL(上)SqlClient、DDL、查询】
|
14天前
|
SQL Java 流计算
Flink(十三)【Flink SQL(上)SqlClient、DDL、查询】(3)
Flink(十三)【Flink SQL(上)SqlClient、DDL、查询】
|
14天前
|
SQL 消息中间件 存储
Flink(十三)【Flink SQL(上)SqlClient、DDL、查询】(2)
Flink(十三)【Flink SQL(上)SqlClient、DDL、查询】
|
8天前
|
SQL
SQL查询
SQL查询
14 0
|
11天前
|
SQL 安全 数据库
SQL实践指南:从基础到进阶的数据库查询与管理
一、引言 在数据驱动的时代,数据库已成为各行各业不可或缺的一部分
|
11天前
|
SQL 安全 数据库
掌握SQL:数据库操作与查询的精髓
一、引言 在数据驱动的时代,数据库是任何组织或项目不可或缺的一部分
|
11天前
|
SQL 存储 数据库
掌握SQL:数据库查询与管理的关键技能
一、引言 在信息化快速发展的今天,数据库已成为存储、处理和查询数据的重要工具

推荐镜像

更多