以下是我的情景:
表image_book_rel
包含两个表之间的关系,即book_table
和image_table
。
我需要从表格book_table
获取图书清单以及表格image_table
中的相关图片数据(如果有)。
这里大概是表格的样子(简化):
/* book_table */
id title price
-------- ---------- ------
1 Book 1 $10
2 Book 2 $13
3 Book 3 $15
4 Book 4 $20
5 Book 5 $12
6 Book 6 $10
7 Book 7 $14
/* image_table */
id description file
-------- ---------------- -------------
20 Image of Book 2 book_img2.jpg
30 Image of Book 3 book_img3.jpg
50 book_img5.jpg
70 Image of Book 7 book_img7.jpg
/* image_book_rel */
id book_id image_id
-------- --------- ---------
1 2 20
2 3 30
3 5 50
4 7 70
以下是我查询结果所需的内容:
/* Expected result: */
book_id image_id filename book_title img_desc
-------- --------- --------------- ----------- -----------------
1 Book 1
2 20 book_img2.jpg Book 2 Image of Book 2
3 30 book_img3.jpg Book 3 Image of Book 3
4 Book 4
5 50 book_img5.jpg Book 5
6 Book 6
7 70 book_img7.jpg Book 7 Image of Book 7
以下是我的尝试:
SELECT bk.id AS book_id, im.id AS image_id, im.file AS filename, bk.title AS book_title, im.description AS img_desc
FROM book_table AS bk
LEFT JOIN image_book_rel AS bi
ON bk.id = bi.book_id
LEFT JOIN image_table AS im
ON bi.image_id = im.id
WHERE bk.id = bk.id
AND bi.book_id = bk.id
AND bi.image_id = im.id
ORDER BY bk.id
上述查询的结果会检索 ONLY 包含图片的图书。我需要检索所有图书。我该怎么做?
答案 0 :(得分:3)
尝试不使用WHERE
并使用IFNULL
将空值替换为空字符串:
SELECT IFNULL(bk.id,'') AS book_id, IFNULL(im.id,'') AS image_id, IFNULL(im.file,'') AS filename, IFNULL(bk.title,'') AS book_title, IFNULL(im.description,'') AS img_desc
FROM book_table AS bk
LEFT JOIN image_book_rel AS bi
ON bk.id = bi.book_id
LEFT JOIN image_table AS im
ON bi.image_id = im.id
ORDER BY bk.id
结果:
BOOK_ID IMAGE_ID FILENAME BOOK_TITLE IMG_DESC
1 Book 1
2 20 book_img2.jpg Book 2 Image of Book 2
3 30 book_img3.jpg Book 3 Image of Book 3
4 Book 4
5 50 book_img5.jpg Book 5
6 Book 6
7 70 book_img7.jpg Book 7 Image of Book 7
请参阅SQL Fiddle中的结果。
答案 1 :(得分:2)
你正在混合两种类型的JOIN sintax。您拥有的WHERE子句是复制LEFT JOIN子句(这是您想要的),但它等同于实现INNER JOIN,它排除没有图像的行。
正确的查询更简单:
SELECT bk.id AS book_id, im.id AS image_id, im.file AS filename, bk.title AS book_title, im.description AS img_desc
FROM book_table AS bk
LEFT JOIN image_book_rel AS bi
ON bk.id = bi.book_id
LEFT JOIN image_table AS im
ON bi.image_id = im.id
ORDER BY bk.id
进一步细化答案...... WHERE条件
bk.id = bk.id
绝对无用,而WHERE条件:
bi.book_id = bk.id
bi.image_id = im.id
通过过滤掉具有NULL im.id的行,使您已经指定的LEFT JOINS无效。这些条件会产生与查询相同的结果:
SELECT bk.id AS book_id, im.id AS image_id, im.file AS filename, bk.title AS book_title, im.description AS img_desc
FROM book_table AS bk
JOIN image_book_rel AS bi
ON bk.id = bi.book_id
JOIN image_table AS im
ON bi.image_id = im.id
ORDER BY bk.id