当前位置: 首页 > news >正文

板凳-------Mysql cookbook学习 (十一--------5)

12.4 产生主从列表和摘要

mysql> select artist.name, painting.title-> from artist inner join painting on artist.a_id = painting.a_id-> order by name, title;
+----------+-------------------+
| name     | title             |
+----------+-------------------+
| Da Vinci | Mona Lisa         |
| Da Vinci | The Last Supper   |
| Renoir   | Les Deux Soeurs   |
| Van Gogh | Starry Night      |
| Van Gogh | The Potato Eaters |
| Van Gogh | The Rocks         |
+----------+-------------------+
6 rows in set (0.00 sec)
•	只返回两个表中匹配的记录(即artist.a_id等于painting.a_id的记录)。
•	结果:
o	没有作品的艺术家(如Monet)会被排除。
o	最终结果只有 6 条记录。mysql> select artist.name, painting.title-> from artist left join painting on artist.a_id = painting.a_id-> order by name, title;
+----------+-------------------+
| name     | title             |
+----------+-------------------+
| Da Vinci | Mona Lisa         |
| Da Vinci | The Last Supper   |
| Monet    | NULL              |
| Renoir   | Les Deux Soeurs   |
| Van Gogh | Starry Night      |
| Van Gogh | The Potato Eaters |
| Van Gogh | The Rocks         |
+----------+-------------------+
7 rows in set (0.00 sec)
作用:返回左表(artist)的所有记录,以及右表(painting)中匹配的记录。如果右表中没有匹配项,则用NULL填充。
结果:
所有艺术家(包括没有作品的Monet)都会被保留。
Monet的title列为NULL,表示他没有对应的作品。
最终结果有 7 条记录。
INNER JOIN:只需要两个表中都存在关联数据的记录时。
LEFT JOIN:需要保留左表的所有数据,即使右表中没有匹配项(如统计每个艺术家的作品数,包括没有作品的艺术家)。mysql> select a_id, count(a_id) as count from painting group by a_id;
+------+-------+
| a_id | count |
+------+-------+
|    1 |     2 |
|    3 |     3 |
|    4 |     1 |
+------+-------+
3 rows in set (0.00 sec)mysql> select artist.name as painter, count(painting.a_id) as count-> from artist inner join painting on artist.a_id = painting.a_id-> group by artist.name;
+----------+-------+
| painter  | count |
+----------+-------+
| Da Vinci |     2 |
| Van Gogh |     3 |
| Renoir   |     1 |
+----------+-------+
3 rows in set (0.00 sec)
•	连接类型:INNER JOIN 只保留两表中匹配的记录。
•	聚合逻辑:COUNT(painting.a_id) 统计每个艺术家的有效作品数(即 painting.a_id 不为 NULL 的记录)。
•	结果:
o	没有作品的艺术家(如 Monet)被排除。
o	每个画家的 count 等于其作品数量。mysql> select artist.name as painter, count(painting.a_id) as count-> from artist left join painting on artist.a_id = painting.a_id-> group by artist.name;
+----------+-------+
| painter  | count |
+----------+-------+
| Da Vinci |     2 |
| Monet    |     0 |
| Renoir   |     1 |
| Van Gogh |     3 |
+----------+-------+
4 rows in set (0.00 sec)
•	连接类型:LEFT JOIN 保留左表(artist)的所有记录,右表无匹配时用 NULL 填充。
•	聚合逻辑:COUNT(painting.a_id) 统计每个艺术家的有效作品数(忽略 NULL)。
•	结果:
o	所有艺术家(包括 Monet)被保留。
o	Monet 的 count 为 0,因为他没有作品(painting.a_id 全为 NULL)。mysql> select artist.name as painter, count(*) as count-> from artist left join painting on artist.a_id = painting.a_id-> group by artist.name;
+----------+-------+
| painter  | count |
+----------+-------+
| Da Vinci |     2 |
| Monet    |     1 |
| Renoir   |     1 |
| Van Gogh |     3 |
+----------+-------+
4 rows in set (0.00 sec)
连接类型:LEFT JOIN 保留左表的所有记录。
聚合逻辑:COUNT(*) 统计每个艺术家的总记录数(无论 painting.a_id 是否为 NULL)。
结果:
所有艺术家被保留。
Monet 的 count 为 1,因为 LEFT JOIN 为他生成了一条记录(painting 字段全为 NULL)。
核心区别总结
查询	连接类型	COUNT 统计对象	无作品艺术家的处理
1. INNER + COUNT(a_id)	INNER	有效作品数	排除(如 Monet 不显示)
2. LEFT + COUNT(a_id)	LEFT	有效作品数	保留,count=0
3. LEFT + COUNT(*)	LEFT	总记录数	保留,count=1(生成的 NULL 行)
示例对比(以 Monet 为例)
INNER JOIN:Monet 被完全排除,因为他没有匹配的作品。
LEFT JOIN + COUNT(painting.a_id):Monet 显示,但 COUNT 忽略 NULL,结果为 0LEFT JOIN + COUNT(*):Monet 显示,COUNT 包含生成的 NULL 行,结果为 1。
应用场景
统计作品数:用 LEFT JOIN + COUNT(painting.a_id)(包含无作品的艺术家)。
统计关联行数:用 LEFT JOIN + COUNT(*)(如计算每个艺术家在结果集中的行数)。
纯匹配数据:用 INNER JOIN(只关注有作品的艺术家)。
mysql> select artist.name as painter,-> count(painting.a_id) as 'number of paintings',-> sum(painting.price) as  'total price',-> avg(painting.price) as 'average price'-> from artist left join painting on artist.a_id = painting.a_id-> group by artist.name;
+----------+---------------------+-------------+---------------+
| painter  | number of paintings | total price | average price |
+----------+---------------------+-------------+---------------+
| Da Vinci |                   2 |         121 |       60.5000 |
| Monet    |                   0 |        NULL |          NULL |
| Renoir   |                   1 |          64 |       64.0000 |
| Van Gogh |                   3 |         148 |       49.3333 |
+----------+---------------------+-------------+---------------+
4 rows in set (0.01 sec)mysql> select artist.name as painter,-> count(painting.a_id) as 'number of paintings',-> ifnull(sum(painting.price),0) as  'total price',-> ifnull(avg(painting.price), 0) as 'average price'-> from artist left join painting on artist.a_id = painting.a_id-> group by artist.name;
+----------+---------------------+-------------+---------------+
| painter  | number of paintings | total price | average price |
+----------+---------------------+-------------+---------------+
| Da Vinci |                   2 |         121 |       60.5000 |
| Monet    |                   0 |           0 |        0.0000 |
| Renoir   |                   1 |          64 |       64.0000 |
| Van Gogh |                   3 |         148 |       49.3333 |
+----------+---------------------+-------------+---------------+
4 rows in set (0.00 sec)

12.5 枚举多对多的关系

mysql> select name, abbrev from states;
+----------------+--------+
| name           | abbrev |
+----------------+--------+
| Alaska         | AK     |
| Alabama        | AL     |
| Arkansas       | AR     |
| Arizona        | AZ     |
| California     | CA     |
| Colorado       | CO     |
| Connecticut    | CT     |
| Delaware       | DE     |
| Florida        | FL     |
| Georgia        | GA     |
| Hawaii         | HI     |
| Iowa           | IA     |
| Idaho          | ID     |
| Illinois       | IL     |
| Indiana        | IN     |
| Kansas         | KS     |
| Kentucky       | KY     |
| Louisiana      | LA     |
| Massachusetts  | MA     |
| Maryland       | MD     |
| Maine          | ME     |
| Michigan       | MI     |
| Minnesota      | MN     |
| Missouri       | MO     |
| Mississippi    | MS     |
| Montana        | MT     |
| North Carolina | NC     |
| North Dakota   | ND     |
| Nebraska       | NE     |
| New Hampshire  | NH     |
| New Jersey     | NJ     |
| New Mexico     | NM     |
| Nevada         | NV     |
| New York       | NY     |
| Ohio           | OH     |
| Oklahoma       | OK     |
| Oregon         | OR     |
| Pennsylvania   | PA     |
| Rhode Island   | RI     |
| South Carolina | SC     |
| South Dakota   | SD     |
| Tennessee      | TN     |
| Texas          | TX     |
| Utah           | UT     |
| Virginia       | VA     |
| Vermont        | VT     |
| Washington     | WA     |
| Wisconsin      | WI     |
| West Virginia  | WV     |
| Wyoming        | WY     |
+----------------+--------+
50 rows in set (0.00 sec)mysql> select title, state from painting order by state;
+-------------------+-------+
| title             | state |
+-------------------+-------+
| The Rocks         | IA    |
| The Last Supper   | IN    |
| Starry Night      | KY    |
| The Potato Eaters | KY    |
| Mona Lisa         | MI    |
| Les Deux Soeurs   | NE    |
+-------------------+-------+
6 rows in set (0.00 sec)mysql> select painting.title, states.name as state-> from painting inner join states on painting.state = states.abbrev-> order by state;
+-------------------+----------+
| title             | state    |
+-------------------+----------+
| The Last Supper   | Indiana  |
| The Rocks         | Iowa     |
| Starry Night      | Kentucky |
| The Potato Eaters | Kentucky |
| Mona Lisa         | Michigan |
| Les Deux Soeurs   | Nebraska |
+-------------------+----------+
6 rows in set (0.00 sec)-- 创建表(已正确创建)
CREATE TABLE euchre (team        CHAR(10) NOT NULL,      -- 队伍名称year        YEAR NOT NULL,          -- 比赛年份wins        INT UNSIGNED NOT NULL,  -- 胜场数losses      INT UNSIGNED NOT NULL,  -- 负场数player      CHAR(20) NOT NULL,      -- 队员姓名player_city CHAR(20) NOT NULL       -- 队员城市
);-- 插入数据(修正表名和列)
INSERT INTO euchre (team, year, wins, losses, player, player_city)
VALUES('Kings', 2005, 10, 2, 'Alice', 'New York'),('Kings', 2005, 10, 2, 'Bob', 'New York'),('Crowns', 2005, 7, 5, 'Charlie', 'Chicago'),('Crowns', 2005, 7, 5, 'Diana', 'Chicago'),('Stars', 2005, 4, 8, 'Eve', 'Los Angeles'),('Stars', 2005, 4, 8, 'Frank', 'Los Angeles'),('Sceptres', 2005, 3, 9, 'Grace', 'Houston'),('Sceptres', 2005, 3, 9, 'Heidi', 'Houston'),('Kings', 2006, 8, 4, 'Alice', 'New York'),('Kings', 2006, 8, 4, 'Bob', 'New York'),('Crowns', 2006, 9, 3, 'Ivan', 'Chicago'),('Crowns', 2006, 9, 3, 'Judy', 'Chicago'),('Stars', 2006, 5, 7, 'Ken', 'Los Angeles'),('Stars', 2006, 5, 7, 'Lisa', 'Los Angeles'),('Sceptres', 2006, 2, 10, 'Mike', 'Houston'),('Sceptres', 2006, 2, 10, 'Nancy', 'Houston');mysql> select * from euchre order by year, wins desc, player;
+----------+------+------+--------+---------+-------------+
| team     | year | wins | losses | player  | player_city |
+----------+------+------+--------+---------+-------------+
| Kings    | 2005 |   10 |      2 | Alice   | New York    |
| Kings    | 2005 |   10 |      2 | Bob     | New York    |
| Crowns   | 2005 |    7 |      5 | Charlie | Chicago     |
| Crowns   | 2005 |    7 |      5 | Diana   | Chicago     |
| Stars    | 2005 |    4 |      8 | Eve     | Los Angeles |
| Stars    | 2005 |    4 |      8 | Frank   | Los Angeles |
| Sceptres | 2005 |    3 |      9 | Grace   | Houston     |
| Sceptres | 2005 |    3 |      9 | Heidi   | Houston     |
| Crowns   | 2006 |    9 |      3 | Ivan    | Chicago     |
| Crowns   | 2006 |    9 |      3 | Judy    | Chicago     |
| Kings    | 2006 |    8 |      4 | Alice   | New York    |
| Kings    | 2006 |    8 |      4 | Bob     | New York    |
| Stars    | 2006 |    5 |      7 | Ken     | Los Angeles |
| Stars    | 2006 |    5 |      7 | Lisa    | Los Angeles |
| Sceptres | 2006 |    2 |     10 | Mike    | Houston     |
| Sceptres | 2006 |    2 |     10 | Nancy   | Houston     |
+----------+------+------+--------+---------+-------------+
16 rows in set (0.00 sec)mysql> -- 创建 euchre_team 表
mysql> CREATE TABLE IF NOT EXISTS euchre_team (->   id        INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,  -- 自增主键->   name      CHAR(10) NOT NULL,                        -- 队伍名称->   year      YEAR NOT NULL,                            -- 比赛年份->   wins      INT UNSIGNED NOT NULL,                    -- 胜场数->   losses    INT UNSIGNED NOT NULL,                    -- 负场数->   UNIQUE KEY team_year_idx (name, year)               -- 确保每个队伍在同一年份只能有一条记录-> );
Query OK, 0 rows affected (0.10 sec)mysql>
mysql> -- 插入数据
mysql> INSERT INTO euchre_team (name, year, wins, losses)-> VALUES->   ('Kings', 2005, 10, 2),->   ('Crowns', 2005, 7, 5),->   ('Stars', 2005, 4, 8),->   ('Sceptres', 2005, 3, 9),->   ('Kings', 2006, 8, 4),->   ('Crowns', 2006, 9, 3),->   ('Stars', 2006, 5, 7),->   ('Sceptres', 2006, 2, 10);
Query OK, 8 rows affected (0.01 sec)
Records: 8  Duplicates: 0  Warnings: 0mysql>
mysql> -- 查询所有数据
mysql> SELECT * FROM euchre_team;
+----+----------+------+------+--------+
| id | name     | year | wins | losses |
+----+----------+------+------+--------+
|  1 | Kings    | 2005 |   10 |      2 |
|  2 | Crowns   | 2005 |    7 |      5 |
|  3 | Stars    | 2005 |    4 |      8 |
|  4 | Sceptres | 2005 |    3 |      9 |
|  5 | Kings    | 2006 |    8 |      4 |
|  6 | Crowns   | 2006 |    9 |      3 |
|  7 | Stars    | 2006 |    5 |      7 |
|  8 | Sceptres | 2006 |    2 |     10 |
+----+----------+------+------+--------+
8 rows in set (0.00 sec)
mysql> DROP TABLE IF EXISTS euchre_player;
Query OK, 0 rows affected, 1 warning (0.01 sec)mysql> #@ _CREATE_EUCHRE_PLAYER_TABLE_
mysql> CREATE TABLE euchre_player-> (->   id    INT UNSIGNED NOT NULL AUTO_INCREMENT,->   name  CHAR(20) NOT NULL,    # player name and city->   city  CHAR(20) NOT NULL,->   PRIMARY KEY (id)-> );
Query OK, 0 rows affected (0.04 sec)mysql> #@ _CREATE_EUCHRE_PLAYER_TABLE_
mysql>
mysql> INSERT INTO euchre_player (name,city)->   VALUES->     ('Ben','Cork'),->     ('Billy','York'),->     ('Tony','Derry'),->     ('Melvin','Dublin'),->     ('Franklin','Bath'),->     ('Wallace','Cardiff'),->     ('Nigel','London'),->     ('Maurice','Leeds')-> ;
Query OK, 8 rows affected (0.01 sec)
Records: 8  Duplicates: 0  Warnings: 0mysql>
mysql> SELECT * FROM euchre_player;
+----+----------+---------+
| id | name     | city    |
+----+----------+---------+
|  1 | Ben      | Cork    |
|  2 | Billy    | York    |
|  3 | Tony     | Derry   |
|  4 | Melvin   | Dublin  |
|  5 | Franklin | Bath    |
|  6 | Wallace  | Cardiff |
|  7 | Nigel    | London  |
|  8 | Maurice  | Leeds   |
+----+----------+---------+
8 rows in set (0.00 sec)mysql> DROP TABLE IF EXISTS euchre_link;
Query OK, 0 rows affected, 1 warning (0.01 sec)mysql> #@ _CREATE_EUCHRE_LINK_TABLE_
mysql> CREATE TABLE euchre_link-> (->   team_id   INT UNSIGNED NOT NULL,->   player_id INT UNSIGNED NOT NULL,->   UNIQUE (team_id, player_id)-> );
Query OK, 0 rows affected (0.06 sec)mysql> #@ _CREATE_EUCHRE_LINK_TABLE_
mysql>
mysql> INSERT INTO euchre_link (team_id,player_id)->   VALUES->     (1,1),->     (1,2),->     (2,3),->     (2,4),->     (3,5),->     (3,6),->     (4,7),->     (4,8),->     (5,5),->     (5,7),->     (6,1),->     (6,3),->     (7,4),->     (7,8),->     (8,2),->     (8,6)-> ;
Query OK, 16 rows affected (0.01 sec)
Records: 16  Duplicates: 0  Warnings: 0mysql>
mysql> SELECT * FROM euchre_link;
+---------+-----------+
| team_id | player_id |
+---------+-----------+
|       1 |         1 |
|       1 |         2 |
|       2 |         3 |
|       2 |         4 |
|       3 |         5 |
|       3 |         6 |
|       4 |         7 |
|       4 |         8 |
|       5 |         5 |
|       5 |         7 |
|       6 |         1 |
|       6 |         3 |
|       7 |         4 |
|       7 |         8 |
|       8 |         2 |
|       8 |         6 |
+---------+-----------+
16 rows in set (0.00 sec)mysql> select t.name, t.year, t.wins, t.losses, p.name, p.city-> from euchre_team as t inner join euchre_link as l-> inner join euchre_player as p-> on t.id = l.team_id and p.id = l.player_id-> order by t.year, t.wins desc, p.name;
+----------+------+------+--------+----------+---------+
| name     | year | wins | losses | name     | city    |
+----------+------+------+--------+----------+---------+
| Kings    | 2005 |   10 |      2 | Ben      | Cork    |
| Kings    | 2005 |   10 |      2 | Billy    | York    |
| Crowns   | 2005 |    7 |      5 | Melvin   | Dublin  |
| Crowns   | 2005 |    7 |      5 | Tony     | Derry   |
| Stars    | 2005 |    4 |      8 | Franklin | Bath    |
| Stars    | 2005 |    4 |      8 | Wallace  | Cardiff |
| Sceptres | 2005 |    3 |      9 | Maurice  | Leeds   |
| Sceptres | 2005 |    3 |      9 | Nigel    | London  |
| Crowns   | 2006 |    9 |      3 | Ben      | Cork    |
| Crowns   | 2006 |    9 |      3 | Tony     | Derry   |
| Kings    | 2006 |    8 |      4 | Franklin | Bath    |
| Kings    | 2006 |    8 |      4 | Nigel    | London  |
| Stars    | 2006 |    5 |      7 | Maurice  | Leeds   |
| Stars    | 2006 |    5 |      7 | Melvin   | Dublin  |
| Sceptres | 2006 |    2 |     10 | Billy    | York    |
| Sceptres | 2006 |    2 |     10 | Wallace  | Cardiff |
+----------+------+------+--------+----------+---------+
16 rows in set (0.00 sec)mysql> select p.name, p.city-> from euchre_team as t inner join euchre_link as l-> inner join euchre_player as p-> on t.id = l.team_id and p.id = l.player_id-> and t.name = 'Crowns' and t.year = 2005;
+--------+--------+
| name   | city   |
+--------+--------+
| Tony   | Derry  |
| Melvin | Dublin |
+--------+--------+
2 rows in set (0.00 sec)mysql> select t.name, t.year, t.wins, t.losses-> from euchre_team as t inner join euchre_link as l-> inner join euchre_player as p-> on t.id = l.team_id and p.id = l.player_id-> where p.name = 'Billy';
+----------+------+------+--------+
| name     | year | wins | losses |
+----------+------+------+--------+
| Kings    | 2005 |   10 |      2 |
| Sceptres | 2006 |    2 |     10 |
+----------+------+------+--------+
2 rows in set (0.00 sec)
http://www.dtcms.com/a/270232.html

相关文章:

  • 《每日AI-人工智能-编程日报》--2025年7月8日
  • Softhub软件下载站实战开发(十六):仪表盘前端设计与实现
  • 香港风水(原生)林地的逻辑分类器
  • 缺乏项目进度预警机制,如何建立预警体系
  • 从零开始手写嵌入式实时操作系统
  • 【c++八股文】Day4:右值,右值引用,移动语义
  • 使用协程简化异步资源获取操作
  • qt-C++语法笔记之Stretch与Spacer的关系分析
  • Python Web应用开发之Flask框架高级应用(三)——蓝图(Blueprints)
  • openssl 生成国密证书
  • 北京-4年功能测试2年空窗-报培训班学测开-第四十五天
  • [附源码+数据库+毕业论文]基于Spring+MyBatis+MySQL+Maven+vue实现的供电公司安全生产考试管理系统,推荐!
  • 【OD机试题解法笔记】跳马
  • MySQL8.0.40.0MSI安装教程
  • [特殊字符] AlphaGo:“神之一手”背后的智能革命与人机博弈新纪元
  • 汽车功能安全系统阶段开发【技术安全方案TSC以及安全分析】5
  • TypeScript 接口全解析:从基础到高级应用
  • Crazyflie无人机集群控制笔记(一)通过VRPN实时对接Crazyswarm2与NOKOV度量动捕数据
  • 数据湖技术之Iceberg-03 Iceberg整合Flink 实时写入与增量读取
  • Linux文件描述符与标准I/O终极对比
  • BabelDOC,一个专为学术PDF文档设计的翻译和双语对比工具
  • C#使用Semantic Kernel实现Embedding功能
  • 解决GitHub仓库推送子文件夹后打不开的问题
  • C++高频知识点(六)
  • vue3使用inspira-ui教程【附带源码】
  • Ansible 介绍及安装
  • ubuntu24.04(vmware workstation 17.6pro)无法安装vmtools的问题解决
  • mini-program01の系统认识微信小程序开发
  • 云原生详解:构建现代化应用的未来
  • 【读论文】GLM-4.1V-Thinking 解读:用强化学习解锁 VLM 的通用推理能力