龙空技术网

读SQL学习指南(第3版)笔记06_连接和集合

躺着的柒 88

前言:

现在同学们对“sqlserver查询语法”大致比较关心,看官们都需要了解一些“sqlserver查询语法”的相关内容。那么小编在网摘上汇集了一些关于“sqlserver查询语法””的相关文章,希望大家能喜欢,咱们快快来了解一下吧!

1. 连接1.1. 笛卡儿积1.1.1. 交叉连接(cross join)1.1.2. 查询并没有指定两个数据表应该如何连接,数据库服务器就生成了笛卡儿积1.1.2.1. 两个数据表的所有排列组合1.1.3. 很少会用到(至少不会特意用到)1.1.3.1. 使用频率并不高1.1.4. mysql

-> SELECT c.first_name, c.last_name, a.address    -> FROM customer c JOIN address a;
1.1.5. 为2020年的每一天生成一行,但是数据库中没有包含每天一行的数据表1.1.5.1. 涉及交叉连接、外连接、日期函数、分组、集合运算(union all)和聚合函数(count())1.1.5.2. sql
 SELECT '2020-01-01' dtUNION ALLSELECT '2020-01-02' dtUNION ALLSELECT '2020-01-03' dtUNION ALL.........SELECT '2020-12-29' dtUNION ALLSELECT '2020-12-30' dtUNION ALLSELECT '2020-12-31' dt
1.1.5.3. mysql
 -> SELECT ones.num + tens.num + hundreds.num    -> FROM    -> (SELECT 0 num UNION ALL    -> SELECT 1 num UNION ALL    -> SELECT 2 num UNION ALL    -> SELECT 3 num UNION ALL    -> SELECT 4 num UNION ALL    -> SELECT 5 num UNION ALL    -> SELECT 6 num UNION ALL    -> SELECT 7 num UNION ALL    -> SELECT 8 num UNION ALL    -> SELECT 9 num) ones    -> CROSS JOIN    -> (SELECT 0 num UNION ALL    -> SELECT 10 num UNION ALL    -> SELECT 20 num UNION ALL    -> SELECT 30 num UNION ALL    -> SELECT 40 num UNION ALL    -> SELECT 50 num UNION ALL    -> SELECT 60 num UNION ALL    -> SELECT 70 num UNION ALL    -> SELECT 80 num UNION ALL    -> SELECT 90 num) tens    -> CROSS JOIN    -> (SELECT 0 num UNION ALL    -> SELECT 100 num UNION ALL    -> SELECT 200 num UNION ALL    -> SELECT 300 num) hundreds;
1.1.5.4. 如果生成{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}、{0, 10, 20, 30, 40, 50, 60, 70, 80, 90}和{0,100, 200, 300}这3个集合的笛卡儿积,并将这3列的值相加,就可以得到包含0~399的所有数值的400行结果集1.1.5.5. mysql
 -> SELECT DATE_ADD('2020-01-01',    ->   INTERVAL (ones.num + tens.num + hundreds.num) DAY) dt    -> FROM    ->  (SELECT 0 num UNION ALL    ->   SELECT 1 num UNION ALL    ->   SELECT 2 num UNION ALL    ->   SELECT 3 num UNION ALL    ->   SELECT 4 num UNION ALL    ->   SELECT 5 num UNION ALL    ->   SELECT 6 num UNION ALL    ->   SELECT 7 num UNION ALL    ->   SELECT 8 num UNION ALL    ->   SELECT 9 num) ones    ->   CROSS JOIN    ->  (SELECT 0 num UNION ALL    ->   SELECT 10 num UNION ALL    ->   SELECT 20 num UNION ALL    ->   SELECT 30 num UNION ALL    ->   SELECT 40 num UNION ALL    ->   SELECT 50 num UNION ALL    ->   SELECT 60 num UNION ALL    ->   SELECT 70 num UNION ALL    ->   SELECT 80 num UNION ALL    ->   SELECT 90 num) tens    ->   CROSS JOIN    ->  (SELECT 0 num UNION ALL    ->   SELECT 100 num UNION ALL    ->   SELECT 200 num UNION ALL    ->   SELECT 300 num) hundreds    -> WHERE DATE_ADD('2020-01-01',    ->   INTERVAL (ones.num + tens.num + hundreds.num) DAY) < '2021-01-01'    -> ORDER BY 1;
1.1.5.6. 无须人为介入,结果集会自动包含额外的闰日(2月29日),这是由数据库服务器通过将2020年1月1日加上59天计算得出1.2. 内连接1.2.1. 增加了连接类型(注意关键字inner)1.2.2. mysql
 -> SELECT c.first_name, c.last_name, a.address    -> FROM customer c JOIN address a    ->   ON c.address_id = a.address_id;
1.2.3. sql
SELECT c.first_name, c.last_name, a.addressFROM customer c INNER JOIN address a  ON c.address_id = a.address_id;
1.2.4. 如果用于连接两个数据表的列名相同,则可以使用using子句替代on1.2.4.1. sql
SELECT c.first_name, c.last_name, a.addressFROM customer c INNER JOIN address a  USING (address_id);
1.2.4.2. using是一种只能在某些特定情况下使用的简写表示法1.3. 外连接(outer join)1.3.1. 如果要将一个数据表中的所有行全部纳入结果集,不管其在另一个数据表中是否存在匹配1.3.2. mysql
 -> SELECT f.film_id, f.title, count(i.inventory_id) num_copies    -> FROM film f    ->   LEFT OUTER JOIN inventory i    ->   ON f.film_id = i.film_id    -> GROUP BY f.film_id, f.title;
1.3.3. 关键字left和right只是告知服务器哪个数据表的数据可以不足1.3.4. outer关键字是可选的,可以使用A left join B来代替1.4. 自然连接(natural join)1.4.1. 依靠多个数据表之间相同的列名来推断适合的连接条件1.4.2. mysql
 -> SELECT c.first_name, c.last_name, date(r.rental_date)    -> FROM customer c    ->   NATURAL JOIN rental r;Empty set (0.04 sec)
1.4.3. 数据库服务器检查数据表定义并添加了连接条件r.customer_id = c.customer_id1.4.4. 应该避免使用这种连接类型,而使用带有显式连接条件的内连接1.5. 连接的旧方法1.5.1. mysql
 -> SELECT c.first_name, c.last_name, a.address    -> FROM customer c, address a    -> WHERE c.address_id = a.address_id;
1.5.2. 不需要on子句1.5.3. from子句中的数据表名以逗号分隔1.5.4. 连接条件出现在where子句中1.6. ANSI连接语法1.6.1. 连接条件和过滤条件被分隔在两个不同的子句中(on子句和where子句),使得查询语句更易于理解1.6.2. 两个数据表的连接条件出现在其各自单独的on子句中,这样就不太可能错误地忽略连接条件1.6.3. 使用SQL92连接语法的查询语句可以在各种数据库服务器间移植,而旧语法在不同服务器上的表现略有不同1.7. 连接顺序1.7.1. 各数据表在from子句中出现的顺序并不重要1.7.1.1. 服务器使用从数据库对象收集的统计信息,在3个数据表中选择一个作为起点(所选择的数据表被称为驱动表),然后确定其他数据表的连接顺1.7.2. 如果认为查询语句中的数据表应该始终以特定的顺序连接,可以将数据表按照需要的顺序排列1.7.2.1. 在MySQL中指定straight_join关键字1.7.2.1.1. sql
SELECT STRAIGHT_JOIN c.first_name, c.last_name, ct.cityFROM city ct  INNER JOIN address a  ON a.city_id = ct.city_id  INNER JOIN customer c  ON c.address_id = a.address_id
1.7.2.2. 在SQL Server中请求force order选项1.7.2.3. 在Oracle Database中使用ordered或leading优化器1.7.3. 三路外连接1.7.3.1. mysql
-> SELECT f.film_id, f.title, i.inventory_id, r.rental_date    -> FROM film f    ->   LEFT OUTER JOIN inventory i    ->   ON f.film_id = i.film_id    ->   LEFT OUTER JOIN rental r    ->   ON i.inventory_id = r.inventory_id    -> WHERE f.film_id BETWEEN 13 AND 15;
1.8. 自连接1.8.1. mysql
-> SELECT f.title, f_prnt.title prequel    -> FROM film f    ->   INNER JOIN film f_prnt    ->   ON f_prnt.film_id = f.prequel_film_id    -> WHERE f.prequel_film_id IS NOT NULL;
2. 集合2.1. 在对两个数据集执行集合运算时2.1.1. 两个数据集的列数必须相等2.1.2. 两个数据集各列的数据类型必须相同2.1.2.1. 数据库服务器必须能够将一种数据类型转换成另一种数据类型2.2. union运算符2.2.1. mysql
 -> SELECT 1 num, 'abc' str    -> UNION    -> SELECT 9 num, 'xyz' str;
2.2.2. union会对组合后的集合进行排序并去除重复项2.2.3. union all则不然2.3. intersect运算符2.3.1. ANSI SQL规范中定义了用于执行交集运算的intersect运算符2.3.2. ANSI SQL规范还提供了不去除重复行的intersect all运算符2.3.2.1. 唯一实现了intersect all运算符的数据库服务器是IBM DB2 Universal Server2.3.3. MySQL 8.0版还未实现intersect运算符2.3.4. Oracle或SQL Server 2008中可以使用2.4. except运算符2.4.1. ANSI SQL规范提供了执行差集运算的except运算符2.4.2. ANSI SQL规范还提供了except all运算符2.4.2.1. 只有IBM的 DB2 Universal Server实现了该运算符2.4.3. MySQL 8.0版也没有实现except运算符2.4.4. Oracle Database需要使用非ANSI兼容的minus运算符替代except运算符2.5. 对符合查询结果排序2.5.1. mysql
 -> SELECT a.first_name fname, a.last_name lname    -> FROM actor a    -> WHERE a.first_name LIKE 'J%' AND a.last_name LIKE 'D%'    -> UNION ALL    -> SELECT c.first_name, c.last_name    -> FROM customer c    -> WHERE c.first_name LIKE 'J%' AND c.last_name LIKE 'D%'    -> ORDER BY lname, fname;
2.6. 集合运算的优先级2.6.1. 包含3个或以上查询语句的复合查询,是以自顶向下的顺序来评估查询的2.6.2. 根据ANSI SQL规范,intersect运算符拥有比其他集合运算符更高的优先级2.6.3. 可以将查询放入括号内,以明确指定查询的执行顺序2.6.3.1. MySQL目前还不允许在复合查询中使用括号2.6.3.2. 将相邻查询放入括号中,以覆盖复合查询默认的自顶向下的处理方式

标签: #sqlserver查询语法 #mysql逗号隔开 #mysqlminus