SQL查询从多个表返回数据

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL查询从多个表返回数据相关的知识,希望对你有一定的参考价值。

我想知道以下内容:

  • 如何从我的数据库中的多个表中获取数据?
  • 有什么类型的方法可以做到这一点?
  • 什么是联盟和联盟?它们如何彼此不同?
  • 我应该何时使用每一个与其他人相比?

我打算在我的(例如 - php)应用程序中使用它,但不想对数据库运行多个查询,我有什么选项可以从单个查询中的多个表中获取数据?

注意:我正在写这篇文章,因为我希望能够链接到我在PHP队列中经常遇到的众多问题的精心编写的指南,因此我可以在发布答案时链接到此以获取更多详细信息。

答案涵盖以下内容:

  1. Part 1 - Joins and Unions
  2. Part 2 - Subqueries
  3. Part 3 - Tricks and Efficient Code
  4. Part 4 - Subqueries in the From Clause
  5. Part 5 - Mixed Bag of John's Tricks
答案

Part 1 - Joins and Unions

这个答案包括:

  1. 第1部分 使用内连接连接两个或多个表(有关其他信息,请参阅wikipedia entry) 如何使用联合查询 左右外连接(这个stackOverflow answer非常适合描述连接类型) 相交查询(以及如果数据库不支持它们如何重现它们) - 这是SQL-Server(see info)的一个功能,首先是reason I wrote this whole thing的一部分。
  2. 第2部分 子查询 - 它们是什么,它们可以在哪里使用以及需要注意什么 笛卡尔加入了AKA - 哦,痛苦!

有许多方法可以从数据库中的多个表中检索数据。在这个答案中,我将使用ANSI-92连接语法。这可能与许多使用旧版ANSI-89语法的其他教程不同(如果你习惯了89,可能看起来不那么直观 - 但我只能说是尝试它),因为它更容易了解查询何时开始变得更复杂。为什么要用它?是否有性能提升? short answer不是,但是一旦你习惯它就会更容易阅读。使用此语法更容易读取其他人编写的查询。

我还将使用一个小型caryard的概念,它有一个数据库来跟踪它有哪些可用的汽车。所有者已雇用您作为他的IT计算机人员,并希望您能够将他所要求的数据丢给他。

我已经制作了一些将由最终表使用的查找表。这将为我们提供一个合理的模型。首先,我将针对具有以下结构的示例数据库运行查询。我将尝试思考在开始时所犯的常见错误,并解释它们出了什么问题 - 当然还要说明如何纠正错误。

第一个表格只是一个颜色列表,以便我们知道我们在车场里有什么颜色。

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)

品牌表标识了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)

模型表将涵盖不同类型的汽车,使用不同的汽车类型而不是实际的汽车模型会更简单。

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)

最后,要将所有这些其他表格捆绑在一起,将所有这些表格联系在一起。 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)

这将为我们提供足够的数据(我希望),以覆盖不同类型的连接的下面的示例,并提供足够的数据,使它们值得。

因此,老板想知道他拥有的所有跑车的身份证。

这是一个简单的两个表连接。我们有一个表格,用于识别模型和包含可用库存的表格。如您所见,model表的cars列中的数据与我们所拥有的models表的cars列有关。现在,我们知道模型表的1的ID为Sports,所以让我们编写连接。

select
    ID,
    model
from
    cars
        join models
            on model=ID

那么这个查询看起来不错吧?我们已经确定了两个表并包含了我们需要的信息,并使用了一个正确标识要加入的列的连接。

ERROR 1052 (23000): Column 'ID' in field list is ambiguous

哦,不!我们的第一个查询出错了!是的,这是一个梅花。你看,查询确实得到了正确的列,但是其中一些列存在于两个表中,因此数据库对我们所指的实际列和位置感到困惑。有两种解决方案可以解决这个问题。第一个是好的和简单的,我们可以使用tableName.columnName告诉数据库我们的意思,如下所示:

select
    cars.ID,
    models.model
from
    cars
        join models
            on cars.model=models.ID

+----+--------+
| ID | model  |
+----+--------+
|  1 | Sports |
|  3 | Sports |
|  8 | Sports |
| 10 | Sports |
|  2 | Sedan  |
|  4 | Sedan  |
|  5 | 4WD    |
|  7 | 4WD    |
|  9 | 4WD    |
|  6 | Luxury |
+----+--------+
10 rows in set (0.00 sec)

另一种可能更常用,称为表别名。这个例子中的表有简短的简单名称,但输入像KPI_DAILY_SALES_BY_DEPARTMENT这样的东西可能会很快变老,所以一个简单的方法就是像这样昵称表:

select
    a.ID,
    b.model
from
    cars a
        join models b
            on a.model=b.ID

现在,回到请求。正如您所看到的,我们拥有所需的信息,但我们也有未被要求的信息,因此我们需要在声明中包含where子句,以便按照要求获得跑车。由于我更喜欢​​表别名方法而不是一遍又一遍地使用表名,因此我将从这一点开始坚持使用它。

显然,我们需要在查询中添加一个where子句。我们可以通过ID=1model='Sports'识别跑车。由于ID已被索引并且主键(并且它恰好是较少键入),因此我们在查询中使用它。

select
    a.ID,
    b.model
from
    cars a
        join models b
            on a.model=b.ID
where
    b.ID=1

+----+--------+
| ID | model  |
+----+--

以上是关于SQL查询从多个表返回数据的主要内容,如果未能解决你的问题,请参考以下文章

易语言中如何从SQL查询中返回结果?

SQL总结

从一个表中的多个表中计数代码返回 0

如何从 Access 2010 中的 SQL 存储过程返回多个记录集

如何将SQL Server中多个表的数据一次性返回到一张EXCEL工作表(Sheet)中

SQL 从多个表中选择列而不重复数据