繁体   English   中英

在MySQL的一个结果集中从多个表获取数据

[英]Get data from multiple tables in one result set in MySQL

在我正在使用的小型图书馆/研究数据库应用程序中,我有一个页面,用户可以在其中查看他们提交的所有资源。

我有用于不同资源的三个表格-书籍,期刊和会议。 这些表如下所示:

mysql> desc book;
+---------------+------------------+------+-----+---------+----------------+
| Field         | Type             | Null | Key | Default | Extra          |
+---------------+------------------+------+-----+---------+----------------+
| id            | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| author        | varchar(255)     | YES  |     | NULL    |                |
| publishedyear | char(4)          | YES  |     | NULL    |                |
| title         | varchar(255)     | YES  |     | NULL    |                |
| edition       | int(3) unsigned  | YES  |     | NULL    |                |
| publisher     | varchar(100)     | YES  |     | NULL    |                |
| place         | varchar(50)      | YES  |     | NULL    |                |
| image         | varchar(100)     | YES  |     | NULL    |                |
| isbn          | varchar(20)      | YES  |     | NULL    |                |
| callnumber    | varchar(30)      | YES  |     | NULL    |                |
| status        | int(1) unsigned  | YES  |     | NULL    |                |
| abstract      | text             | YES  |     | NULL    |                |
| toc           | text             | YES  |     | NULL    |                |
| problems      | text             | YES  |     | NULL    |                |
| futurework    | text             | YES  |     | NULL    |                |
| registered    | datetime         | YES  |     | NULL    |                |
| mid           | int(10) unsigned | NO   | MUL | NULL    |                |
| iid           | int(10) unsigned | NO   | MUL | NULL    |                |
+---------------+------------------+------+-----+---------+----------------+
18 rows in set (0.00 sec)

mysql> desc journal;
+---------------+------------------+------+-----+---------+----------------+
| Field         | Type             | Null | Key | Default | Extra          |
+---------------+------------------+------+-----+---------+----------------+
| id            | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| author        | varchar(255)     | YES  |     | NULL    |                |
| publishedyear | char(4)          | YES  |     | NULL    |                |
| title         | varchar(255)     | YES  |     | NULL    |                |
| journaltitle  | varchar(255)     | YES  |     | NULL    |                |
| volume        | int(3) unsigned  | YES  |     | NULL    |                |
| issue         | int(5) unsigned  | YES  |     | NULL    |                |
| pagenumbers   | varchar(15)      | YES  |     | NULL    |                |
| image         | varchar(100)     | YES  |     | NULL    |                |
| isbn          | varchar(20)      | YES  |     | NULL    |                |
| callnumber    | varchar(30)      | YES  |     | NULL    |                |
| status        | int(1) unsigned  | YES  |     | NULL    |                |
| abstract      | text             | YES  |     | NULL    |                |
| toc           | text             | YES  |     | NULL    |                |
| problems      | text             | YES  |     | NULL    |                |
| futurework    | text             | YES  |     | NULL    |                |
| registered    | datetime         | YES  |     | NULL    |                |
| mid           | int(10) unsigned | NO   | MUL | NULL    |                |
| iid           | int(10) unsigned | NO   | MUL | NULL    |                |
+---------------+------------------+------+-----+---------+----------------+
19 rows in set (0.00 sec)

mysql> desc conference;
+----------------+------------------+------+-----+---------+----------------+
| Field          | Type             | Null | Key | Default | Extra          |
+----------------+------------------+------+-----+---------+----------------+
| id             | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| author         | varchar(255)     | YES  |     | NULL    |                |
| publishedyear  | char(4)          | YES  |     | NULL    |                |
| title          | varchar(255)     | YES  |     | NULL    |                |
| conferencename | varchar(255)     | YES  |     | NULL    |                |
| location       | varchar(100)     | YES  |     | NULL    |                |
| conferencedate | varchar(15)      | YES  |     | NULL    |                |
| pagenumbers    | varchar(15)      | YES  |     | NULL    |                |
| image          | varchar(100)     | YES  |     | NULL    |                |
| isbn           | varchar(20)      | YES  |     | NULL    |                |
| callnumber     | varchar(30)      | YES  |     | NULL    |                |
| status         | int(1) unsigned  | YES  |     | NULL    |                |
| abstract       | text             | YES  |     | NULL    |                |
| toc            | text             | YES  |     | NULL    |                |
| problems       | text             | YES  |     | NULL    |                |
| futurework     | text             | YES  |     | NULL    |                |
| registered     | datetime         | YES  |     | NULL    |                |
| mid            | int(10) unsigned | NO   | MUL | NULL    |                |
| iid            | int(10) unsigned | NO   | MUL | NULL    |                |
+----------------+------------------+------+-----+---------+----------------+
19 rows in set (0.00 sec)

我想做的很简单,但是似乎找不到一个简单的SQL命令。 在堆栈溢出和Google上搜索“从多个表中选择数据”以及其他类似的搜索,对于数据库和操作的复杂复杂的联接,联合等,返回的结果很多,比我在这里尝试的要复杂得多。

是否没有类似的东西:

Select * FROM book, journal, conference WHERE mid = 4'

这将返回错误:“字段中间不明确”。

谢谢!

**编辑-正如martijn指出的那样,我的很多问题都来自数据库的设计。

两种解决方案似乎是重新设计数据库并将bookjournalconference合并为一个表resources

或者,作为一种非常棘手的解决方法

要执行三个单独的查询:

SELECT * FROM book where mid = 4

SELECT * FROM journal WHERE mid = 4

SELECT * FROM conference WHERE mid =4

然后使用PHP组合这些结果集。

我认为您正在寻找UNION:

select 'book' as item_type, * from book where mid = 4
union all
select 'journal' as item_type, * from journal where mid = 4
union all
select 'conference' as item_type, * from conference where mid = 4

当然,假设您尝试一次搜索所有三个表,并且它们确实具有相同的列结构。 当然,在实际的应用程序中,您将显式列出列,而不是使用*来确保列以正确的顺序出现。 另外,我还随意添加了item_type以便您可以弄清楚每个条目来自哪里表。

可能是由于数据库设计而出现问题的原因。 据我所知,这三个表的定义是相同的。 也许您应该使它成为一个带有ENUM字段的表,该字段指定条目是书籍,期刊还是会议。 编辑:我刚刚看到这不是一个简单的选择:您仍然需要单独的表格来获取特定于书籍,期刊和会议的信息。

如果您不想这样做,则需要指定一些问题。 您是否要使三个表中的行mid等于4? 在这种情况下,您必须使用UNION 如果您想要一行以mid = 4给您书籍,日记和会议,请使用JOmasrutter已经指出的JOIN

编辑:既然您指出了您想要查询返回的内容,最好使用'mu is too short'解决方案。 添加字段是一个很好的解决方案(为此,需要+1)。

不过,我认为您应该考虑使用ENUM选项。 我不知道会破坏什么功能,但是如果您最初是从jounals选择的, jounals修复查询将归结为添加WHERE kind = 'journal'

您可以通过join实现。

MySQL中最简单的联接类型与您已经尝试过的联接非常相似。 您所拥有的问题是它不知道您指的是哪个“中间”。 实际上,您希望所有三个元素都等于一个常数。

SELECT * FROM book, journal, conference
WHERE book.mid = 4 AND journal.mid = 4 AND conference.mid = 4

哪个应该很容易理解。

还有其他表达相同联接的方法-例如:

SELECT * FROM
  book
  INNER JOIN journal ON journal.mid = book.mid
  INNER JOIN conference ON conference.mid = book.mid
WHERE
  book.mid = 4

...表示完全相同的内容,但是一旦您获得了比这更复杂的查询,将连接条件与其他WHERE子句分开可能会更好地读取-一旦您熟悉语法。

应该注意的是,联接是用于您想要合并表中的行的。 如果存在多个会议或多个书籍等,所有这些都具有所需的“中”值,则将针对这些组合的每种组合返回一行。 因此,如果有4本书,2个会议和2种期刊具有相同的“中”值,您将获得4 x 2 x 2 = 16行返回。 这是因为在这种情况下,您要告诉MySQL“告诉我可以使用这些值找到的书籍,会议和期刊的每种组合”。

我不知道应用程序是什么,所以我不知道这是否是您想要的。 但是,如果您不希望这样做,并且只对分别从每个表中检索行而不是将它们组合在一起感兴趣,那么最好将其表示为三个单独的查询。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM