在我正在处理的小型图书馆/研究数据库应用程序中,我有一个页面,用户可以在其中查看他们提交的所有资源。
我有三张不同资源的表格 - 书籍,期刊和会议。表格如下所示:
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命令。搜索堆栈溢出和谷歌“从多个表中选择数据”和其他类似的搜索返回了很多结果,对于数据库和操作来说,这些复杂的连接,联合等等比我在这里尝试的要复杂得多。
是否有类似的东西:
Select * FROM book, journal, conference WHERE mid = 4'
这会返回一个错误:“field mid is ambiguous”。
谢谢!
**编辑 - 正如martijn指出的那样,我的很多问题都来自我的数据库设计。
两个解决方案似乎是重新设计数据库并将book
,journal
和conference
合并到一个表resources
或者,作为一种非常糟糕的解决方法
要执行三个单独的查询:
SELECT * FROM book where mid = 4
SELECT * FROM journal WHERE mid = 4
SELECT * FROM conference WHERE mid =4
然后使用PHP组合这些结果集。
答案 0 :(得分:5)
我认为你正在寻找一个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
,以便您可以找出每个条目来自哪个表。
答案 1 :(得分:5)
可能是因为数据库设计而遇到麻烦的原因。这三个表的定义(据我所知)是相同的。也许您应该使用ENUM
字段创建一个表,指定该条目是书籍,期刊还是会议。
编辑:我刚刚看到这不是一个简单的选择:你仍然需要单独的表格来获取特定于书籍,期刊和会议的信息。
如果您不想这样做,则需要指明一些问题。你想让三个表中mid
等于4的行吗?在这种情况下,您必须使用UNION
。如果您希望一行为您提供有mid = 4
的书籍,期刊和会议,请使用JOIN
,正如thomasrutter已经指出的那样。
不过,我认为您应该考虑使用ENUM
选项。我不知道哪些功能会破坏,但如果您最初从WHERE kind = 'journal'
进行选择,则修复查询会归结为添加jounals
。
答案 2 :(得分:4)
您可以使用 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“告诉我你能用这些价值找到的书籍,会议和期刊的每一个组合”。
我不知道应用程序是什么,所以我不知道这是不是你想要的。但是,如果您不想这样做,并且您只想分别从每个表中检索行而不是将它们组合起来,那么它可能更好地表示为三个单独的查询。