我有一个名为 Chapters 的表,其中包含 5 个书籍字段(book1、book2 等)和 5 个产品字段(product1、product2 等),以及一些其他不必要的字段,但是我已经包含了每个记录都唯一的 key (文件名),以防万一。
章节
| filename | title | book1 | book2 | book3 | book4 | book5 | product1 | product2 | product3 | product4 | product5 |
|------------|---------|---------|-------|--------|-------|-------|-----------|----------|-----------|----------|----------|
| file1.pdf | Title1 | Book1 | | | | | Product4 | | | | |
| file2.pdf | Title2 | Book9 | | | | | Product1 | Product4 | | | |
| file3.pdf | Title3 | Book4 | | | | | Product5 | | | | |
| file4.pdf | Title4 | Book7 | | | | | Product1 | | | | |
| file5.pdf | Title5 | Book21 | | | | | Product13 | Product9 | Product11 | | |
| file6.pdf | Title6 | Book5 | | | | | Product23 | Product3 | | | |
| file7.pdf | Title7 | Book675 | | | | | Product45 | Product6 | | | |
| file8.pdf | Title8 | Book3 | Book5 | | | | Product9 | | | | |
| file9.pdf | Title9 | Book1 | Book7 | Book34 | | | Product77 | | | | |
| file10.pdf | Title10 | Book22 | | | | | Product3 | | | | |
我最终需要执行 2 个查询。第一个是获取所有可能的书籍以及任何关联产品的列表,第二个是镜像,所有可能的产品以及关联的书籍列表。基本相同,只是信息的镜像。这是一个期望的最终结果。
| books | products |
|---------|--------------------------------|
| Book1 | Product4, Product77 |
| Book21 | Product13, Product9, Product11 |
| Book22 | Product3 |
| Book3 | Product9 |
| Book34 | Product77 |
| Book4 | Product5 |
| Book5 | Product9, Product23, Product3 |
| Book675 | Product45, Product6 |
| Book7 | Product77, Product1 |
| Book9 | Product1, Product4 |'
我已经尝试了大量的选择(不要问需要多少时间),但以下内容让我非常接近,但我得到了空白图书列表,并且得到了重复项(book1 将出现两次,等等)。
SELECT booklist.books,
concat_ws(', ',
IF(LENGTH(chapters.product1),chapters.product1, NULL),
IF(LENGTH(chapters.product2),chapters.product2, NULL),
IF(LENGTH(chapters.product3),chapters.product3, NULL),
IF(LENGTH(chapters.product4),chapters.product4, NULL),
IF(LENGTH(chapters.product5),chapters.product5, NULL))
AS products
FROM
(SELECT book1 AS books FROM chapters
UNION
SELECT book2 FROM chapters
UNION
SELECT book3 FROM chapters
UNION
SELECT book4 FROM chapters
UNION
SELECT book5 FROM chapters) booklist
JOIN
chapters ON chapters.book1 = booklist.books
OR chapters.book2 = booklist.books
OR chapters.book3 = booklist.books
OR chapters.book4 = booklist.books
OR chapters.book5 = booklist.books
ORDER BY booklist.books;
这给了我以下内容:
| books | products |
|---------|--------------------------------|
| | Product13, Product9, Product11 |
| | Product1 |
| | Product5 |
| | Product1, Product4 |
| | Product3 |
| | Product4 |
| | Product77 |
| | Product9 |
| | Product45, Product6 |
| | Product23, Product3 |
| Book1 | Product4 |
| Book1 | Product77 |
| Book21 | Product13, Product9, Product11 |
| Book22 | Product3 |
| Book3 | Product9 |
| Book34 | Product77 |
| Book4 | Product5 |
| Book5 | Product9 |
| Book5 | Product23, Product3 |
| Book675 | Product45, Product6 |
| Book7 | Product77 |
| Book7 | Product1 |
| Book9 | Product1, Product4 |
那么最后,我如何摆脱空记录并合并多本书。数据集绝不会超过 200-300 条记录。感谢您阅读本文!
这是一个sqlfiddle
最佳答案
如果您无法规范化模式,则使用 View 进行“动态伪规范化”:
CREATE VIEW books AS
SELECT `filename`, `book1` As `book` FROM chapters
UNION
SELECT `filename`, `book2` FROM chapters
UNION
SELECT `filename`, `book3` FROM chapters
UNION
SELECT `filename`, `book4` FROM chapters
UNION
SELECT `filename`, `book5` FROM chapters
;
CREATE VIEW products AS
SELECT `filename`, `product1` As `product` FROM chapters
UNION
SELECT `filename`, `product2` FROM chapters
UNION
SELECT `filename`, `product3` FROM chapters
UNION
SELECT `filename`, `product4` FROM chapters
UNION
SELECT `filename`, `product5` FROM chapters
;
然后以与规范化模式类似的方式对这些 View 进行查询,例如:
SELECT `book`,
group_concat( `product` ) products
FROM books b
JOIN products p USING (`filename`)
WHERE b.`book` IS NOT NULL
AND p.`product` IS NOT NULL
GROUP BY `book`
;
演示:http://sqlfiddle.com/#!9/8717d/2
但是我们警告您 - 这种方法会(非常)慢。
您能做的最好的事情就是标准化架构。
关于php - SQL SELECT 与联合子查询的连接返回空和多个结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31413237/