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

简介:
最近一来因工作上的事情比较闹心,没心事再研究 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 ,如需转载请自行联系原作者
相关文章
|
4月前
|
SQL 监控 关系型数据库
一键开启百倍加速!RDS DuckDB 黑科技让SQL查询速度最高提升200倍
RDS MySQL DuckDB分析实例结合事务处理与实时分析能力,显著提升SQL查询性能,最高可达200倍,兼容MySQL语法,无需额外学习成本。
|
4月前
|
SQL 存储 关系型数据库
MySQL体系结构详解:一条SQL查询的旅程
本文深入解析MySQL内部架构,从SQL查询的执行流程到性能优化技巧,涵盖连接建立、查询处理、执行阶段及存储引擎工作机制,帮助开发者理解MySQL运行原理并提升数据库性能。
|
4月前
|
SQL 监控 关系型数据库
SQL优化技巧:让MySQL查询快人一步
本文深入解析了MySQL查询优化的核心技巧,涵盖索引设计、查询重写、分页优化、批量操作、数据类型优化及性能监控等方面,帮助开发者显著提升数据库性能,解决慢查询问题,适用于高并发与大数据场景。
|
5月前
|
SQL Web App开发 安全
SQL Server 2025 年 8 月更新 - 修复 CVE-2025-49759 SQL Server 特权提升漏洞
SQL Server 2025 年 8 月更新 - 修复 CVE-2025-49759 SQL Server 特权提升漏洞
439 2
SQL Server 2025 年 8 月更新 - 修复 CVE-2025-49759 SQL Server 特权提升漏洞
|
5月前
|
SQL XML Java
通过MyBatis的XML配置实现灵活的动态SQL查询
总结而言,通过MyBatis的XML配置实现灵活的动态SQL查询,可以让开发者以声明式的方式构建SQL语句,既保证了SQL操作的灵活性,又简化了代码的复杂度。这种方式可以显著提高数据库操作的效率和代码的可维护性。
378 18
|
3月前
|
SQL 关系型数据库 MySQL
(SQL)SQL语言中的查询语句整理
查询语句在sql中占了挺大一部分篇幅,因为在数据库中使用查询语句的次数远多于更新与删除命令。而查询语句比起其他语句要更加的复杂,可因为sql是数据库不可或缺的一部分,所以即使不懂,也必须得弄懂,以上。
283 0
|
4月前
|
SQL Web App开发 安全
SQL Server 2025 年 9 月更新 - 修复 CVE-2025-47997 SQL Server 信息泄露漏洞
SQL Server 2025 年 9 月更新 - 修复 CVE-2025-47997 SQL Server 信息泄露漏洞
220 0
SQL Server 2025 年 9 月更新 - 修复 CVE-2025-47997 SQL Server 信息泄露漏洞
|
5月前
|
SQL 容灾 安全
云时代SQL Server的终极答案:阿里云 RDS SQL Server如何用异地容灾重构系统可靠性
在数字化转型的浪潮中,数据库的高可用性已成为系统稳定性的生命线。作为经历过多次生产事故的资深开发者,肯定深知传统自建SQL Server架构的脆弱性——直到遇见阿里云 RDS SQL Server,其革命性的异地容灾架构彻底改写了游戏规则。
|
6月前
|
SQL Web App开发 安全
SQL Server 2025年7月更新 - 修复 CVE-2025-49718 Microsoft SQL Server 信息泄露漏洞
SQL Server 2025年7月更新 - 修复 CVE-2025-49718 Microsoft SQL Server 信息泄露漏洞
476 0
SQL Server 2025年7月更新 - 修复 CVE-2025-49718 Microsoft SQL Server 信息泄露漏洞
|
5月前
|
SQL 人工智能 数据库
【三桥君】如何正确使用SQL查询语句:避免常见错误?
三桥君解析了SQL查询中的常见错误和正确用法。AI产品专家三桥君通过三个典型案例:1)属性重复比较错误,应使用IN而非AND;2)WHERE子句中非法使用聚合函数的错误,应改用HAVING;3)正确的分组查询示例。三桥君还介绍了学生、课程和选课三个关系模式,并分析了SQL查询中的属性比较、聚合函数使用和分组查询等关键概念。最后通过实战练习帮助读者巩固知识,强调掌握这些技巧对提升数据库查询效率的重要性。
197 0

推荐镜像

更多
  • DNS