SELECT*FROM employees
WHERE salary >(-- 括号中的就是子查询SELECTAVG(salary)FROM employees
)
2. IN 运算符结合子查询
SELECT*FROM clients
WHERE client_id NOTIN(SELECTDISTINCT client_id
FROM invoices
);
3. 子查询 vs 连接 选择可读性更好的
本例中子查询的更易读懂,但有时候添加子查询会使查询太复杂,这时候更适合用连接。
-- 把第二章 IN运算的查询,使用连接来改写SELECT*FROM clients
-- 使用左连接,clients表中的数据都会显示,不管client_id在invoices表中是否存在LEFTJOIN invoices USING(client_id)WHERE invoice_id ISNULL-- 练习:筛选出购买了生菜(product_id = 3)的顾客信息-- product_id在order_items表中可以查到,顾客信息存在于customers表中-- orders表存在与customers表关联的customer_id,orders表还存在与order_items表关联的order_id-- 子查询SELECT
customer_id,
first_name,
last_name
FROM customers
WHERE customer_id IN(SELECT o.customer_id
FROM order_items oi
JOIN orders o USING(order_id)WHERE product_id =3);-- 连接SELECTDISTINCT
c.customer_id,
c.first_name,
c.last_name
FROM customers c
JOIN orders o USING(customer_id)JOIN order_items oi USING(order_id)WHERE oi.product_id =3;
4. ALL 关键字
-- 使用聚合函数MAX实现,查询出所有比客户3最大发票额大的发票SELECT*FROM invoices
WHERE invoice_total >(-- 这里子查询返回的是单一值,用单一值作比较SELECTMAX(invoice_total)FROM invoices
WHERE client_id =3)-- 上面的代码也可以理解为查询金额大于所有客户3金额的发票-- > ALL 与 MAX()可以互换,表示大于查到的所有数值-- < ALL 与 MIN()可以互换,表示小于查到的所有数值SELECT*FROM invoices
-- 下面的子查询等于 WHERE invoice_total > ALL (140,150,160,...) 括号中是子查询中查出的所有数值-- ALL 关键字的操作原理:发票每行都会把发票金额与括号中的这些数字做对比,满足条件的那行就会返回在最终结果集WHERE invoice_total >ALL(-- 这里子查询返回的是一列值,与一列值进行比较SELECT invoice_total
FROM invoices
WHERE client_id =3)
5. ANY 关键字
-- = ANY 与 IN 运算符等效,表示等于子查询中的任意值-- 练习:查询至少有两张发票的客户信息SELECT*FROM clients
-- WEHRE client_id IN () 可以替换成下面-- ANY 关键字的操作原理:client_id等于子查询返回值中的任意一个,该客户的那行就会被返回到最终结果集WHERE client_id =ANY(SELECT client_id
FROM invoices
GROUPBY client_id
HAVINGCOUNT(*)>=2)