mariadb 如何使用两个多对多关联来检索单个SQL选择语句中的所有关联?

bjp0bcyl  于 10个月前  发布在  其他
关注(0)|答案(2)|浏览(67)

我有一个books表,它与genre表和authors表有多对多关联。其目的是在一个单一的选择语句中提取出关于一本书的所有相关信息。
我使用的是MariaDB 10.11,小提琴是10.9
下面是创建和填充表格的代码,我还链接到一个dbfiddle

CREATE TABLE book (id int AUTO_INCREMENT PRIMARY KEY, title varchar(30));
CREATE TABLE author_example (id int AUTO_INCREMENT PRIMARY KEY, name varchar(50));
CREATE TABLE genre (id int AUTO_INCREMENT PRIMARY KEY, genre varchar(50));
CREATE TABLE associate_book_genre (
    genre_id int NOT NULL,
    book_id int NOT NULL,
    CONSTRAINT pk_book_genre PRIMARY KEY (book_id, genre_id)
  );
CREATE TABLE associate_book_author (
    author_id int NOT NULL,
    book_id int NOT NULL,
    CONSTRAINT pk_book_genre PRIMARY KEY (book_id, author_id)
    );

INSERT INTO genre (genre) VALUES ("travel"),("philosophy"),("nonfiction");
INSERT INTO author_example (name) VALUES ("Paul Tillich"),("Douglas Adams"),("Mark Carardine");
INSERT INTO book (title) VALUES ("The Courage to Be"), ("Last Chance to See"),("Beowulf"),("Debate between bird and fish");

字符串
https://dbfiddle.uk/74kXDrRM
我的目标是检索这个表:
| 作者|类型| Genres |
| --|--| ------------ |
| 零|零| null |
| 道格拉斯·亚当斯&马克·卡拉丁|旅行,非小说| travel, nonfiction |
| 保罗·蒂利希|哲学| philosophy |
| 零|零| null |
我最接近的是

SELECT b.title,
  GROUP_CONCAT(a.name SEPARATOR " & ") as author, 
  GROUP_CONCAT(g.genre SEPARATOR ", ") as genre FROM book b 
left join associate_book_author aba on b.id = aba.book_id 
left join author_example a on aba.author_id=a.id 
left join associate_book_genre abg on b.id = abg.book_id 
left join genre g on abg.genre_id =g.id
  group by g.id;


| 作者|类型| Genres |
| --|--| ------------ |
| 零|零| null |
| 道格拉斯·亚当斯&马克·卡拉丁|旅行,旅行| travel, travel |
| 保罗·蒂利希|哲学| philosophy |
| 道格拉斯·亚当斯&马克·卡拉丁|非小说类,非小说类| nonfiction, nonfiction |
然而,我错过了“鸟与鱼之间的辩论”,因为流派是空的“鸟与鱼之间的辩论”和“贝奥武夫”和“最后的机会看到”是列出了两次,流派是错误的。

eoigrqb6

eoigrqb61#

您应该单独聚合作者和流派:

with a as (
 select aa.book_id, GROUP_CONCAT(a.name SEPARATOR " & ") as Authors
 from associate_book_author aa
 join author_example a on a.id = aa.author_id
 group by aa.book_id
), g as (
 select ag.book_id, GROUP_CONCAT(g.genre SEPARATOR ", ") as Genres
 from associate_book_genre ag
 join genre g on g.id = ag.genre_id
 group by ag.book_id
)
select b.title, a.Authors, g.Genres
from book b
left join a on a.book_id = b.id
left join g on g.book_id = b.id
order by b.title;

字符串
修改Fiddle

b09cbbtk

b09cbbtk2#

我改变了分组的方式,并使结果DISTINCT(唯一),而不是像group by g.id那样,我这样做了:GROUP BY b.id, b.title尝试运行此查询:https://dbfiddle.uk/WwUjVeFo

SELECT b.title,
       GROUP_CONCAT(DISTINCT a.name SEPARATOR ' & ') as author,
       GROUP_CONCAT(DISTINCT g.genre SEPARATOR ', ') as genre
FROM book b 
LEFT JOIN associate_book_author aba ON b.id = aba.book_id 
LEFT JOIN author_example a ON aba.author_id = a.id 
LEFT JOIN associate_book_genre abg ON b.id = abg.book_id 
LEFT JOIN genre g ON abg.genre_id = g.id
GROUP BY b.id, b.title
ORDER BY b.title;

字符串


的数据

相关问题