【问题标题】:MySQL: List data with its related data from other tables if availableMySQL:列出数据及其来自其他表的相关数据(如果可用)
【发布时间】:2014-05-13 08:10:29
【问题描述】:

这是我的场景:

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

上述查询的结果检索有图片的图书。我需要检索所有本书。我该怎么办?

【问题讨论】:

    标签: mysql sql database select join


    【解决方案1】:

    尝试不使用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 中查看结果。

    【讨论】:

      【解决方案2】:

      您正在混合使用两种类型的 JOIN 语法。您拥有的 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
      

      【讨论】:

      • 感谢您提供有关WHERE 条件的信息
      猜你喜欢
      • 2020-10-02
      • 2014-09-22
      • 2013-09-10
      • 1970-01-01
      • 2016-04-11
      • 2017-06-30
      • 1970-01-01
      • 1970-01-01
      • 2020-09-22
      相关资源
      最近更新 更多