Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
510 views
in Technique[技术] by (71.8m points)

mysql - SQL查询从多个表返回数据(SQL query return data from multiple tables)

I would like to know the following: (我想知道以下内容:)

  • how to get data from multiple tables in my database? (如何从我的数据库中的多个表中获取数据?)
  • what types of methods are there to do this? (有什么类型的方法可以做到这一点?)
  • what are joins and unions and how are they different from one another? (什么是联盟和联盟?它们如何彼此不同?)
  • When should I use each one compared to the others? (我应该何时使用每一个与其他人相比?)

I am planning to use this in my (for example - PHP) application, but don't want to run multiple queries against the database, what options do I have to get data from multiple tables in a single query? (我打算在我的(例如 - PHP)应用程序中使用它,但不想对数据库运行多个查询,我有什么选项可以从单个查询中的多个表中获取数据?)

Note: I am writing this as I would like to be able to link to a well written guide on the numerous questions that I constantly come across in the PHP queue, so I can link to this for further detail when I post an answer. (注意:我正在写这篇文章,因为我希望能够链接到我在PHP队列中经常遇到的众多问题的精心编写的指南,因此我可以在发布答案时链接到此以获取更多详细信息。)

The answers cover off the following: (答案涵盖以下内容:)

  1. Part 1 - Joins and Unions (第1部分 - 联接和联盟)
  2. Part 2 - Subqueries (第2部分 - 子查询)
  3. Part 3 - Tricks and Efficient Code (第3部分 - 技巧和有效代码)
  4. Part 4 - Subqueries in the From Clause (第4部分 - From子句中的子查询)
  5. Part 5 - Mixed Bag of John's Tricks (第5部分 - John's Tricks的混合包)
  ask by community wiki translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Part 1 - Joins and Unions (第1部分 - 联接和联盟)

This answer covers: (这个答案包括:)

  1. Part 1 (第1部分)
  2. Part 2 (第2部分)
    • Subqueries - what they are, where they can be used and what to watch out for (子查询 - 它们是什么,它们可以在哪里使用以及需要注意什么)
    • Cartesian joins AKA - Oh, the misery! (笛卡尔加入了AKA - 哦,痛苦!)

There are a number of ways to retrieve data from multiple tables in a database. (有许多方法可以从数据库中的多个表中检索数据。) In this answer, I will be using ANSI-92 join syntax. (在这个答案中,我将使用ANSI-92连接语法。) This may be different to a number of other tutorials out there which use the older ANSI-89 syntax (and if you are used to 89, may seem much less intuitive - but all I can say is to try it) as it is much easier to understand when the queries start getting more complex. (这可能与许多使用旧版ANSI-89语法的其他教程不同(如果你习惯了89,可能看起来不那么直观 - 但我只能说是尝试它),因为它容易了解查询何时开始变得更复杂。) Why use it? (为什么要用它?) Is there a performance gain? (是否有性能提升?) The short answer is no, but it is easier to read once you get used to it. (简短的回答是否定的,但是一旦你习惯它就会更容易阅读。) It is easier to read queries written by other folks using this syntax. (使用此语法更容易读取其他人编写的查询。)

I am also going to use the concept of a small caryard which has a database to keep track of what cars it has available. (我还将使用一个小型caryard的概念,它有一个数据库来跟踪它有哪些可用的汽车。) The owner has hired you as his IT Computer guy and expects you to be able to drop him the data that he asks for at the drop of a hat. (所有者已雇用您作为他的IT计算机人员,并希望您能够将他所要求的数据丢给他。)

I have made a number of lookup tables that will be used by the final table. (我已经制作了一些将由最终表使用的查找表。) This will give us a reasonable model to work from. (这将为我们提供一个合理的模型。) To start off, I will be running my queries against an example database that has the following structure. (首先,我将针对具有以下结构的示例数据库运行查询。) I will try to think of common mistakes that are made when starting out and explain what goes wrong with them - as well as of course showing how to correct them. (我将尝试思考在开始时所犯的常见错误,并解释它们出了什么问题 - 当然还要说明如何纠正错误。)

The first table is simply a color listing so that we know what colors we have in the car yard. (第一个表格只是一个颜色列表,以便我们知道我们在车场里有什么颜色。)

mysql> create table colors(id int(3) not null auto_increment primary key, 
    -> color varchar(15), paint varchar(10));
Query OK, 0 rows affected (0.01 sec)

mysql> show columns from colors;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(3)      | NO   | PRI | NULL    | auto_increment |
| color | varchar(15) | YES  |     | NULL    |                |
| paint | varchar(10) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

mysql> insert into colors (color, paint) values ('Red', 'Metallic'), 
    -> ('Green', 'Gloss'), ('Blue', 'Metallic'), 
    -> ('White' 'Gloss'), ('Black' 'Gloss');
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> select * from colors;
+----+-------+----------+
| id | color | paint    |
+----+-------+----------+
|  1 | Red   | Metallic |
|  2 | Green | Gloss    |
|  3 | Blue  | Metallic |
|  4 | White | Gloss    |
|  5 | Black | Gloss    |
+----+-------+----------+
5 rows in set (0.00 sec)

The brands table identifies the different brands of the cars out caryard could possibly sell. (品牌表标识了caryard可能出售的汽车的不同品牌。)

mysql> create table brands (id int(3) not null auto_increment primary key, 
    -> brand varchar(15));
Query OK, 0 rows affected (0.01 sec)

mysql> show columns from brands;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(3)      | NO   | PRI | NULL    | auto_increment |
| brand | varchar(15) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)

mysql> insert into brands (brand) values ('Ford'), ('Toyota'), 
    -> ('Nissan'), ('Smart'), ('BMW');
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> select * from brands;
+----+--------+
| id | brand  |
+----+--------+
|  1 | Ford   |
|  2 | Toyota |
|  3 | Nissan |
|  4 | Smart  |
|  5 | BMW    |
+----+--------+
5 rows in set (0.00 sec)

The model table will cover off different types of cars, it is going to be simpler for this to use different car types rather than actual car models. (模型表将涵盖不同类型的汽车,使用不同的汽车类型而不是实际的汽车模型会更简单。)

mysql> create table models (id int(3) not null auto_increment primary key, 
    -> model varchar(15));
Query OK, 0 rows affected (0.01 sec)

mysql> show columns from models;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(3)      | NO   | PRI | NULL    | auto_increment |
| model | varchar(15) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> insert into models (model) values ('Sports'), ('Sedan'), ('4WD'), ('Luxury');
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> select * from models;
+----+--------+
| id | model  |
+----+--------+
|  1 | Sports |
|  2 | Sedan  |
|  3 | 4WD    |
|  4 | Luxury |
+----+--------+
4 rows in set (0.00 sec)

And finally, to tie up all these other tables, the table that ties everything together. (最后,要将所有这些其他表格捆绑在一起,将所有这些表格联系在一起。) The ID field is actually the unique lot number used to identify cars. (ID字段实际上是用于识别汽车的唯一批号。)

mysql> create table cars (id int(3) not null auto_increment primary key, 
    -> color int(3), brand int(3), model int(3));
Query OK, 0 rows affected (0.01 sec)

mysql> show columns from cars;
+-------+--------+------+-----+---------+----------------+
| Field | Type   | Null | Key | Default | Extra          |
+-------+--------+------+-----+---------+----------------+
| id    | int(3) | NO   | PRI | NULL    | auto_increment |
| color | int(3) | YES  |     | NULL    |                |
| brand | int(3) | YES  |     | NULL    |                |
| model | int(3) | YES  |     | NULL    |                |
+-------+--------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

mysql> insert into cars (color, brand, model) values (1,2,1), (3,1,2), (5,3,1), 
    -> (4,4,2), (2,2,3), (3,5,4), (4,1,3), (2,2,1), (5,2,3), (4,5,1);
Query OK, 10 rows affected (0.00 sec)
Records: 10  Duplicates: 0  Warnings: 0

mysql> select * from cars;
+----+-------+-------+-------+
| id | color | brand | model |
+----+-------+-------+-------+
|  1 |     1 |     2 |     1 |
|  2 |     3 |     1 |     2 |
|  3 |     5 |     3 |     1 |
|  4 |     4 |     4 |     2 |
|  5 |     2 |     2 |     3 |
|  6 |     3 |     5 |     4 |
|  7 |     4 |     1 |     3 |
|  8 |     2 |     2 |     1 |
|  9 |     5 |     2 |     3 |
| 10 |     4 |     5 |     1 |
+----+-------+-------+-------+
10 rows in set (0.00 sec)

This will give us enough data (I hope) to cover off the examples below of different types of joins and also give enough data to make them worthwhile. (这将为我们提供足够的数据(我希望),以覆盖不同类型的连接的下面的示例,并提供足够的数据,使它们值得。)

So getting into the grit of it, the boss wants to know The IDs of all the sports cars he has . (因此,老板想知道他拥有的所有跑车的身份证 。)

This is a simple two table join. (这是一个简单的两个表连接。) We have a table that identifies the model and the table with the available stock in it. (我们有一个表格,用于识别模型和包含可用库存的表格。) As you can see, the data in the model column of the cars table relates to the models column of the cars table we have. (如您所见, cars表的model列中的数据与我们拥有的cars表的models列相关。) Now, we know that the models table has an ID of 1 for Sports so lets write the join. (现在,我们知道模型表的Sports ID为1 ,因此我们可以编写连接。)

<c

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...