还可以通过存储过程来查询相关信息,比如EXEC sys.sp_tables; EXEC sys.sp_columns; EXEC sys.sp_help @objname = N'dbo.tableA'等,这种方式不是特别推荐,但sp_help在俺的SQL生涯中确实出现了很多次哦。此外SELECT SERVERPROPERTY('productlevel')可以查询当前数据库实例的版本,这不是重点,想说的是本机的查询结果是RTM,这表示Release to Manufacturing发布到生产制造,即正式版,有时遇到RTM、SP1等是注意理解。
DBCC命令
查看数据库的隔离级别的信息:DBCC USEROPTIONS
在介绍联接前先引出一个概念--表运算符,我们知道FROM字句是第一个被逻辑处理的字句,其中包含表信息,那么对表进行操作的运算符就是表运算符,其中本节要介绍的JOIN是最重要的,很多时候,工作中可能仅仅使用它就足够,此外还是APPLY、PIVOT、UNPIVOT等操作符,之后会介绍。其中JOIN操作符对两个输入表进行操作,类型包括交叉联接、内部联接和外部联接,它们之间的差别在于其逻辑查询处理阶段,这是本节的最需要理解的概念,是真正理解联接操作的基础,通过一个表格来做一个初步的了解(这部分初学时,很容易忽视,但非常重要)。
逻辑查询阶段 笛卡尔乘积 筛选 添加外部行 示例
联接类型
交叉联接 Y N N SELECT u.userid, s.studentid FROM user AS u CROSS JOIN student AS s
内部联接 Y Y N SELECT u.userid, s.studentid FROM user AS u INNER JOIN student AS s ON u.name = s.name
外部联接 Y Y Y SELECT u.userid, s.studentid FROM user AS u INNER JOIN student AS s LEFT JOIN student AS s ON u.name = s.name
之前一直强调的逻辑查询阶段其实相对应与物理查询阶段的,由于数据库查询分析器的存在,有时看起来有性能问题的联接也能运行的很好,所以当遇到查询性能问题时,查看执行计划和分析统计数据非常的重要。
交叉联接:只包含笛卡尔乘积阶段,比如一张表A有m行,表B有n行,其结果集有m*n行记录。该类型使用场景非常少,但其中有2个场景还是需要知道的。
自交叉联接 SELECT e1.empid, e2.empid FROM hr.employee AS e1 CROSS JOIN hr.employee AS e2
生成数字表(有点像数学的辅助函数) 首先在DB中创建一张包含1到10的数字表,之后通过这张表来构建1到1000的数字表 SELECT d3.digit * 100 + d2.digit * 10 + d1.digit + 1 AS n FROM dbo.digits AS d1 CROSS JOIN dbo.digits AS d2 CROSS JOIN dbo.digits AS d3 ORDER BY n 这儿介绍这个的原因是,在实际工作中,为处理异构数据或者按指定格式呈现时,可能需要构建辅助表,埋下这样一个种子就好
内部联接:最常见和基础的联接方式,包含笛卡尔乘积和筛选两个步骤,相对复杂的情形包括复合联接、不等联接和多联接查询,如下表所示。
情形
解释与示例
复合联接
一般在查流水、履历时会遇到这样的场景,因为这时并没有一个唯一的主键标识,需要组合的候选键来查询
SELECT dbo.tableA AS t1 JOIN dbo.tableB AS t2 ON t1.col1 = t2.col1 AND t1.col2 = t2.col2
不等联接
用到不等联接的场景不算太多,一种比较有意思婚配的婚配场景,找到一组人中所有婚配组合(不重复,不并剔除自己和自己配对)
SELECT e1.empid, e2.empid FROM hr.employee AS e1 INNER JOIN hr.employee AS e2 ON e1.empid < e2.empid
多连接查询
SELECT * FROM sales.[order] AS o INNER JOIN sales.orderdetail od ON o.orderid = od.orderid INNER JOIN sales.product p ON od.productid = p.id
自联结
有一个比较典型的例子,就是在员工表找到自己的直属领导
SELECT e1.*, e2.name AS manageName FROM hr.employee AS e1 INNER JOIN hr.employee AS e2 ON e1.manageid = e2.empid