MySQL:列出数据及其他表中的相关数据(如果有)

时间:2014-05-13 08:10:30

标签: mysql sql database select join

以下是我的情景:

image_book_rel包含两个表之间的关系,即book_tableimage_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 包含图片的图书。我需要检索所有图书。我该怎么做?

2 个答案:

答案 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