来自不同表的许多列的 where 子句的语法是什么?

What is the syntax for a where clause for many columns from different tables?

我正在为一个有会议室的地方创建数据库,用于预订和销售书籍。该模式被通用化以允许对多个数据集重复使用 table。

图表略有不正确;有两个 selector table 实际上有不同的名字。右上角的selectortable其实叫option_selector,左下角的values_selector。我用 1, room 填充 resource_type table; 2, book 然后 resource_option1, Name2, size; 3,Author; 4,Publish Year 并用行填充 option_selector table。

我还用一些行填充了 option_selectoroption_value table。然后我运行这个查询

SELECT r.id as 'book ID', v.value as 'Name'
FROM resources r
  JOIN value_selector s ON r.id = s.resource_id
JOIN resourse_option_value v ON s.value_id = v.id
WHERE v.option_selector_id = 3
ORDER BY r.id

结果

book ID    Name
5          Journey to the center of the Earth
6          Oliver Travels
7          C How To Program
8          Java How To Program

这是正确的输出。

问题是我想添加更多数据列来选择 table 与书籍记录,例如 'Author' & 'Publish Year' 使这个输出 table 看起来喜欢

book ID    Name    Author     Publish Year

我试过了

SELECT r.id as 'book ID', v.value as 'Name', v2.value as 'Author', v3.value as 'Year'
FROM resourses r
  JOIN value_selector s ON r.id = s.resourse_id
  JOIN resourse_option_value v ON s.value_id = v.id
  JOIN resourse_option_value v2 ON s.value_id = v2.id
  JOIN resourse_option_value v3 ON s.value_id = v3.id
WHERE
  v.option_selector_id = 3 AND
  v2.option_selector_id = 4 AND
  v3.option_selector_id = 5
ORDER BY r.id

这给出了一个空结果

数据库 sql : http://sqlfiddle.com/#!9/302671/3

我还不清楚你的数据库结构。

但只是为了让您知道从哪里开始,您可以试试这个:

SELECT 
  r.id as 'book ID', 
  MAX(IF(v.option_selector_id = 3,v.value, null)) as 'Name',
  MAX(IF(v.option_selector_id = 4,v.value, null)) as 'Author',
  MAX(IF(v.option_selector_id = 5,v.value, null)) as 'Publish year'
FROM resourses r
JOIN value_selector s
ON r.id = s.resourse_id
JOIN resourse_option_value v
ON s.value_id = v.id
GROUP BY r.id
ORDER BY r.id

我觉得这个查询不会给你带来预期的结果,因为它是依赖于值的查询,我不知道什么是正确的值。因此,如果您提供更多数据样本,我们可以找出您的案例中的正确查询。请提供所有表的示例 and/or sqlfiddle 将是完美的。

编辑 1 因此,如果您只需要书籍,只需添加 WHERE r.type_id = 2 条款:

http://sqlfiddle.com/#!9/302671/12

SELECT 
  r.id as 'book ID', 
  MAX(IF(v.option_selector_id = 3,v.value, null)) as 'Name',
  MAX(IF(v.option_selector_id = 4,v.value, null)) as 'Author',
  MAX(IF(v.option_selector_id = 5,v.value, null)) as 'Publish year'
FROM resourses r
JOIN value_selector s
ON r.id = s.resourse_id
JOIN resourse_option_value v
ON s.value_id = v.id
WHERE r.type_id = 2
GROUP BY r.id
ORDER BY r.id

编辑 2 要获取特定年份的书籍,您可以:

http://sqlfiddle.com/#!9/302671/15

SELECT 
  r.id as 'book ID', 
  MAX(IF(v.option_selector_id = 3,v.value, null)) as 'Name',
  MAX(IF(v.option_selector_id = 4,v.value, null)) as 'Author',
  MAX(IF(v.option_selector_id = 5,v.value, null)) as 'Publish year'
FROM resourses r
JOIN value_selector s
ON r.id = s.resourse_id
JOIN resourse_option_value v
ON s.value_id = v.id
WHERE r.type_id = 2
GROUP BY r.id
HAVING `Publish year`=2014
ORDER BY r.id

好吧,Alex 的回答表明该架构是可行的。在我看来,这仍然很疯狂。特别是,在应该是简单查找语句的地方需要 MAXHAVING 子句对于可伸缩性来说非常重要。为了进行比较,请考虑 Jay 提出的具有单独 table 的模式。

CREATE TABLE `book` (
  `bookId` INT NOT NULL AUTO_INCREMENT,
  `title` VARCHAR(45) NOT NULL,
  `author` VARCHAR(45) NOT NULL,
  `publishYear` INT NOT NULL,
  PRIMARY KEY (`bookId`));

INSERT INTO `book` (`title`, `author`, `publishDate`) VALUES
("Journey to the center of the Earth", "Johny", 2013),
("Oliver Travels", "Ahmed Ali", 2015);

CREATE TABLE `room` (
  `roomId` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NOT NULL
  PRIMARY KEY (`roomId`));

INSERT INTO `room` (`name`) VALUES
  ("Library"), ("Study"), ("Hall"), ("Dining Room"), ("Kitchen"), ("Conservatory"), ("Billiard Room"), ("Lounge"), ("Ballroom");

大功告成。没有空值(这在 MySQL 中不是什么大问题,实际上 reduce storage requirements on the InnoDB engine),没有外键,只有 SQL 的一半才能实现。您可以通过其 table 名称和 ID 轻松判断任何数据记录是什么,而无需检查三个不同的 table 列名称、选项名称和值。

需要这些书吗?

SELECT `bookId`, `title`, `author`, `publishYear` FROM `book`;

从某年开始? (可能要添加出版年份的索引。)

SELECT `bookId`, `title`, `author`, `publishYear` FROM `book`
WHERE `publishYear` = 2013;

需要允许图书有多个作者吗?

CREATE TABLE `author` (
  `authorId` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45),
  `bookId` INT NOT NULL,
  PRIMARY KEY(`authorId`));

ALTER TABLE `book` DROP COLUMN `author`;

SELECT `b`.`bookId`, `title`, GROUP_CONCAT(`name`) as authors, `publishYear`
FROM `book` b
LEFT JOIN `author` a ON `a`.`bookId` = `b`.`bookId`
GROUP BY `b`.`bookId`;

如果您愿意,可以添加外键。