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

时间:2015-04-27 11:56:52

标签: php mysql sql database database-design

我正在为一个有预备会议室的地方创建数据库。卖书。该模式是通用的,允许重用多个数据集的表。

Database Diagram

该图略有不正确;有两个selector表实际上有不同的名称。右上角的selector表实际上称为option_selector,左下角是values_selector。我用resource_type填充1, room表格; 2, book然后resource_option1, Name; 2, size; 3,Author; 4,Publish Year并在option_selector表格中填入行。

  • 1, 1, 1用于将房间映射到名称
  • 2, 1, 2用于将房间映射到大小
  • 3, 2, 1用于将图书映射到名称
  • 4, 2, 3用于将图书映射到作者
  • 5, 2, 4用于将图书映射到发布年份

我还在option_selectoroption_value表中添加了一些行。然后我运行这个查询

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

这是正确的输出。

问题是我想添加更多数据列,以便可以通过书籍记录进行选择,例如“作者”和“作者”。 '发布年'使此输出表看起来像

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

2 个答案:

答案 0 :(得分:1)

我的数据库结构仍然不清楚。

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

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

我觉得这个查询不会带来预期的结果,因为它是值依赖查询,我不知道什么是正确的值。因此,如果您提供更多数据样本,我们可以确定您的案例中的正确查询。请提供所有表格的样本和/或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

答案 1 :(得分:0)

嗯,Alex的回答表明该架构是可行的。在我看来,它仍然非常疯狂。特别是,在简单的查找语句中需要MAXHAVING子句对可伸缩性非常关注。为了进行比较,请考虑使用Jay提出的单独表格的模式。

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可以将它拉下来。您可以通过其表名和ID轻松地告诉任何数据记录是什么,而无需为列名,选项名称和值检查三个不同的表。

需要书籍吗?

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`;

如果您愿意,请添加外键。