文章目录
分组数据
数据分组
分组允许把数据分为多个逻辑组,以便能够对每个组进行聚集计算。
创建分组
分组是在SELECT语句的GROUP BY子句建立的。
SELECT vend_id, COUNT(*) AS num_prods
FROM products
GROUP BY vend_id;
1.GROUP BY子句可以包含任意数目的列。
2.如果在GROUP BY子句中嵌套了分组,数据将在最后规定的分组上进行汇总。
3.GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前。
过滤分组
过滤分组是指规定包括哪些分组,排除哪些分组。WHERE过滤指定的是行,而不是分组,所以不能使用WHERE子句达到过滤分组的目的,MySQL提供了HAVING子句来过滤分组。
SELECT cust_id, COUNT(*) AS orders
FROM orders
GROUP BY cust_id
HAVING COUNT(*) >= 2;
上面的语句过滤COUNT (*) >= 2,两个以上的订单。
分组和排序
OREDER BY 和GROUP BY的差别:
ORDER BY | GROUP BY |
---|---|
排序产生的输出 | 分组行,但输出可能不是分组的顺序 |
任意列都可以使用 | 只可能使用选择列或表达式列,而且必须使用每个选择列表达式 |
不一定需要 | 如果与聚集函数一起使用列,则必须使用 |
SELECT子句顺序
下面为在SELECT语句中使用时,必须遵循的次序:
子句 | 说明 | 是否必须使用 |
---|---|---|
SELECT | 要返回的列或表达式 | 是 |
FROM | 从中检索数据的表 | 仅在从表选择数据时使用 |
WHERE | 行级过滤 | 否 |
GROUP BY | 分组说明 | 仅在按组计算聚集时使用 |
HAVING | 组级过滤 | 否 |
ORDER BY | 输出排序顺序 | 否 |
LIMIT | 要检索的行数 | 否 |
使用子查询
子查询
子查询是嵌套在其他查询中的查询。
利用子查询进行过滤
SELECT cust_id
FROM orders
WHERE order_num IN (200006,200019);
查询具有订单200006和200019的客户ID。
作为计算字段使用子查询
使用子查询的另一方法是创建计算字段。
SELECT cust_name,
cust_state,
(SELECT COUNT(*)
FROM orders
WHERE orders.cust_id = customers.cust_id) AS orders
FROM customers
ORDER BY cust_name;
上面的语句对客户10001的订单进行计数。
联结表
如果数据存储在多个表中,可以用联结检索出数据。
联结的创建非常简单,规定要联结的所有表以及它们如何关联即可:
SELECT vend_name, prod_name, prod_price
FROM vendors, products
WHERE vendors.vend_id = products.vend_id
ORDER BY vend_name, prod_name;
上面的语句指定的prod_name和prod_price在同一个表中。
WHERE子句作为过滤条件,它只包含那些匹配给定条件的行。
由没有联结条件的表关系返回的结果为笛卡儿积,检索出的行的数目将是第一个表中的行数乘以第二个表中的行数。
SELECT vend_name, prod_name, prod_price
FROM vendors INNER JOIN products
ON vendors.vend_id = products.vend_id;
上面的语句返回与前面例子完全相同的数据。
创建高级联结
使用表别名
之前博文里面有介绍过别名用于列名和计算字段,SQL还允许给表名起别名。
FROM customers AS c, orders AS o, orderitems AS oi
使用不同类型的联结
自联结
自联结通常作为外部语句用来替代从相同表中检索数据时使用的子查询语句,虽然最终的结果是一样的,但有时候处理联结远比处理子查询快得多。
例子:
假如发现某物品存在问题,想知道生产该物品的供应商生产的其他物品是否也存在这些问题。
SELECT prod_id, prod_name
FROM products
WHERE vend_id = (SELECT vend_id
FROM products
WHERE prod_id = "DTNTR");
使用带聚集函数的联结
举个例子,如果想要检索所有客户及每个客户所下的订单数,可以使用下面的语句:
SELECT customers.cust_name,
customers.cust_id,
COUNT(orders.order_num) AS num_ord
FROM customers INNER JOIN orders
ON customers.cust_id = orders.cust_id
GROUP BY customers.cust_id;
这里,SELECT语句使用INNER JOIN将customers和orders表互相关联。GRUOP BY子句按客户分组数据。
学习资料来源:
《MySQL必知必会》 Ben Forta 著