索引

Understanding Data Grouping

mysql> SELECT COUNT(*) AS num_prods
-> FROM products
-> WHERE vend_id=1003;
+-----------+
| num_prods |
+-----------+
| 7 |
+-----------+
1 row in set (0.00 sec)

我们可以通过改变 WHERE 条件中与 vend_id 判等的值(1003. 1004. 1005 .. .)来获取各个供货商的产品数量,但是没办法一次性把它们罗列出来,GROUP BY 恰好可以解决这个问题:

mysql> SELECT vend_id, COUNT(*) AS num_prods
-> FROM products
-> GROUP BY vend_id;
+---------+-----------+
| vend_id | num_prods |
+---------+-----------+
| 1001 | 3 |
| 1002 | 2 |
| 1003 | 7 |
| 1005 | 2 |
+---------+-----------+
4 rows in set (0.00 sec)

分组允许把数据分为多个逻辑组,以便能对每个组进行聚集计算。

mysql> SELECT vend_id, COUNT(*) AS num_prods
-> FROM products
-> GROUP BY vend_id WITH ROLLUP;
+---------+-----------+
| vend_id | num_prods |
+---------+-----------+
| 1001 | 3 |
| 1002 | 2 |
| 1003 | 7 |
| 1005 | 2 |
| NULL | 14 |
+---------+-----------+
5 rows in set (0.00 sec)

↑ 利用该 关键字可以同时拿到汇总值。

The GROUP BY clause must come after any WHERE clause and before any ORDER BY clause.

Filtering Groups

mysql> SELECT cust_id, COUNT(*) AS orders
-> FROM orders
-> GROUP BY cust_id
-> HAVING COUNT(*) >= ;
+---------+--------+
| cust_id | orders |
+---------+--------+
| 10001 | 2 |
+---------+--------+
1 row in set (0.00 sec)

如果有 WHERE 那必须是在 GROUP BY 的上面。

WHERE filters before data is grouped, and HAVING filters after data is grouped.

Grouping and Sorting

mysql> SELECT order_num, SUM(quantity*item_price) AS ordertotal
-> FROM orderitems
-> GROUP BY order_num
-> HAVING SUM(quantity*item_price) >= 50
-> ORDER BY ordertotal; # Finally, the output is sorted using the ORDER BY clause.
+-----------+------------+
| order_num | ordertotal |
+-----------+------------+
| 20006 | 55.00 |
| 20008 | 125.00 |
| 20005 | 149.87 |
| 20007 | 1000.00 |
+-----------+------------+
4 rows in set (0.00 sec)

Don't Forget ORDER BY As a rule, anytime you use a GROUP BY clause, you should also specify an ORDER BY clause. That is the only way to ensure that data is sorted properly. Never rely on GROUP BY to sort your data.

总之,最好在用 GROUP BY 的时候顺手给出 ORDER BY , 除非你完全不在意顺序。

多个字段的 GROUP BY 可以参考这篇文章

Understanding Subqueries

设计数据库需要遵循一些范式,而做范式的基本手段就是拆表,因此数据被分散都若干个表中是不可避免的,很多时候,采用子查询会让事情变得更简单。下面是一个简单的例子:

即将用到的几张表 ↓

mysql> SELECT *
-> FROM orders
-> LIMIT 3;
+-----------+---------------------+---------+
| order_num | order_date | cust_id |
+-----------+---------------------+---------+
| | -- :: | |
| | -- :: | |
| | -- :: | |
+-----------+---------------------+---------+

3 rows in set (0.00 sec) mysql> SELECT *
-> FROM orderitems
-> LIMIT 3;
+-----------+------------+---------+----------+------------+
| order_num | order_item | prod_id | quantity | item_price |
+-----------+------------+---------+----------+------------+
| | | ANV01 | | 5.99 |
| | | ANV02 | | 9.99 |
| | | TNT2 | | 10.00 |
+-----------+------------+---------+----------+------------+

3 rows in set (0.00 sec) mysql> SELECT cust_id, cust_name
-> FROM customers
-> LIMIT 3;
+---------+-------------+
| cust_id | cust_name |
+---------+-------------+
| | Coyote Inc. |
| | Mouse House |
| | Wascals |
+---------+-------------+

3 rows in set (0.00 sec)

假设你现在希望得到购买了 TNT2 的顾客的清单,实际上可以分成下面几个查询:

先找出所有 'TNT2' 相关的订单号,然后通过订单号可以找到对应的顾客号,最后通过顾客号再找到顾客信息:

mysql> SELECT order_num
-> FROM orderitems
-> WHERE prod_id = 'TNT2';
+-----------+
| order_num |
+-----------+
| |
| |
+-----------+

2 rows in set (0.00 sec)
mysql> SELECT cust_id
-> FROM orders
-> WHERE order_num IN (,);
+---------+
| cust_id |
+---------+
| |
| |
+---------+

2 rows in set (0.00 sec)

... / 这好几个查询是可以写在一起的:

mysql> SELECT cust_name, cust_contact
-> FROM customers
-> WHERE cust_id IN (SELECT cust_id
-> FROM orders
-> WHERE order_num IN (SELECT order_num
-> FROM orderitems
-> WHERE prod_id = 'TNT2'));
+----------------+--------------+
| cust_name | cust_contact |
+----------------+--------------+
| Coyote Inc. | Y Lee |
| Yosemite Place | Y Sam |
+----------------+--------------+
2 rows in set (0.00 sec)

仅从拿数据的角度分析上面的命令:x. 最终是要拿到 cust_name 和 cust_contact ,所以首先 SELECT cust_name, cust_contact ,从哪里拿呢?FROM customers,约束条件. cust_id 必须在某个集合内,然后 又 回到 x. 重复,一层一层写下去 ...

效率问题:Subqueries and Performance The code shown here works, and it achieves the desired result. However, using subqueries is not always the most efficient way to perform this type of data retrieval, although it might be. More on this is in Chapter 15, "Joining Tables," where you will revisit this same example.

Using Subqueries As Calculated Fields

 相关子查询就像是一个嵌套的 for 循环 ...

SELECT cust_name,
cust_state,
(SELECT COUNT(*)
FROM orders
WHERE orders.cust_id = customers.cust_id) AS orders

FROM customers
ORDER BY cust_name;

使用字段全名是必要的(这可以算是相关子查询的一个特征),否则 mysql 会把 cust_id = cust_id 当成内查询的表字段自己和自己比较。

外查询每找到一条记录就会 执行 一次 子查询,类似于 SELECT x - 2017 ,每找到一条记录都要做一次运算(这里是减2017)。

Build Queries with Subqueries Incrementally Testing and debugging queries with subqueries can be tricky, particularly as these statements grow in complexity. The safest way to build (and test) queries with subqueries is to do so incrementally, in much the same way as MySQL processes them. Build and test the innermost query first. Then build and test the outer query with hard-coded data, and only after you have verified that it is working embed the subquery. Then test it again. And keep repeating these steps as for each additional query. This will take just a little longer to construct your queries, but doing so saves you lots of time later (when you try to figure out why queries are not working) and significantly increases the likelihood of them working the first time.

MySQL Crash Course #06# Chapter 13. 14 GROUP BY. 子查询的更多相关文章

  1. 警惕 MySql 更新 sql 的 WHERE 从句中的 IN() 子查询时出现的性能陷阱

    警惕 MySql 更新 sql 的 WHERE 从句中的 IN() 子查询时出现的性能陷阱 以下文章来源:https://blog.csdn.net/defonds/article/details/4 ...

  2. MySQL Crash Course #07# Chapter 15. 关系数据库. INNER JOIN. VS. nested subquery

    索引 理解相关表. foreign key JOIN 与保持参照完整性 关于JOIN 的一些建议,子查询 VS. 联表查询 我发现MySQL 的官方文档里是有教程的. SQL Tutorial - W ...

  3. 警惕 MySql 更新 sql 的 WHERE 从句中的 IN() 子查询时出现的陷阱

    mer_stage 表有 216423 条记录,DDL: CREATE TABLE `mer_stage` ( `STAGE_ID` int(11) NOT NULL AUTO_INCREMENT, ...

  4. 《mysql必知必会》笔记2(子查询、联接、组合查询、全文本搜索)

    十四:使用子查询 1:子查询是嵌套在其他查询中的查询. 2:需要列出订购TNT2的所有客户信息,需要下面几步: a:从orderitems表中检索出包含物品TNT2的所有订单号: b:根据上一步得出的 ...

  5. Mysql常用sql语句(19)- in / exists 子查询

    测试必备的Mysql常用sql语句系列 https://www.cnblogs.com/poloyy/category/1683347.html 前言 子查询在我们查询方法中是比较常用的,通过子查询可 ...

  6. MySQL Crash Course #04# Chapter 7. 8 AND. OR. IN. NOT. LIKE

    索引 AND. OR 运算顺序 IN Operator VS. OR NOT 在 MySQL 中的表现 LIKE 之注意事项 运用通配符的技巧 Understanding Order of Evalu ...

  7. MySQL Crash Course #15# Chapter 23. Working with Stored Procedures

    以前写过类似的东西,用来自动生成数据. 你可以将 Stored Procedure 理解为可以重复使用的批处理文件. Stored Procedure 非常有用,我们应该尽可能地去使用它. 那么,应用 ...

  8. MySQL Crash Course #11# Chapter 20. Updating and Deleting Data

    INDEX Updating Data The IGNORE Keyword Deleting Data Faster Deletes Guidelines for Updating and Dele ...

  9. MySQL Crash Course #10# Chapter 19. Inserting Data

    INDEX BAD EXAMPLE Improving Overall Performance Inserting Multiple Rows INSTEAD OF Inserting a Singl ...

随机推荐

  1. Visual Studio启用64位 IIS Express 解决 x64位的dll 而出现 未能加载文件或程序集“xxxxxxxx”或它的某一个依赖项。试图加载格式不正确的程序。

  2. Centos7 安装hive

    安装hive 配置hive 在hdfs中新建目录/user/hive/warehouse 首先启动hadoop任务 hdfs dfs -mkdir /tmp hdfs dfs -mkdir /user ...

  3. CodeForces 832B Petya and Exam

    B. Petya and Exam time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  4. 任何时候心中都要有WBS的模版树---产品模块级项目

  5. TACOTRON:端到端的语音合成

    tacotron主要是将文本转化为语音,采用的结构为基于encoder-decoder的Seq2Seq的结构.其中还引入了注意机制(attention mechanism).在对模型的结构进行介绍之前 ...

  6. Oracle安装部署之dbca静默建库和删除库

    dbca查看帮助: [oracle@wen ~]$ dbca -help 1).运行静默建库语句 [oracle@wen ~]$ dbca -silent -cloneTemplate -gdbNam ...

  7. Oracle安装部署之Oracle 10g在redhat5下的安装

    [root@localhost ~]# groupadd dba -g 111 [root@localhost ~]# groupadd oinstall -g 110 [root@localhost ...

  8. Java applets A Java applet example

    https://en.wikipedia.org/wiki/Ajax_(programming) https://zh.wikipedia.org/wiki/AJAX Ajax (also AJAX; ...

  9. 单例模式:Qt本身就提供了专门的宏 Q_GLOBAL_STATIC 通过这个宏不但定义简单,还可以获得线程安全性

    标题起的是有点大 主要是工作和学习中,遇到些朋友,怎么说呢,代码不够Qt化 可能是由于他们一开始接触的是 Java MFC 吧 接触 Qt 7个年头了 希望我的系列文章能抛砖引玉吧 单例模式 很多人洋 ...

  10. 深入浅出 TCP/IP 协议栈

    写的不错:http://www.cnblogs.com/onepixel/p/7092302.html#3899256