【问题标题】:MySQL JOIN, GROUP BY, ORDER BYMySQL JOIN、GROUP BY、ORDER BY
【发布时间】:2012-12-29 07:48:44
【问题描述】:

我有一张产品表:

CREATE TABLE products (`id` INT);

以及这些产品的图片表:

CREATE TABLE images (`id` INT, `product_id` INT, `default` TINYINT(1));

我需要选择所有产品,并加入图像表,以便首选带有 (default = 1) 的图像,如果产品没有带有 (default = 1) 的图像,则使用带有 (default = 1) 的图像(default = 0) 将显示在其位置。


这是一张显示我正在寻找的图片:


现在我有这个查询:

SELECT p.id, i.id
FROM products AS p
LEFT JOIN (
    SELECT product_id, url
    FROM images
    ORDER BY default
) AS i
ON p.id = i.product_id
GROUP BY p.id
ORDER BY p.name

不优先考虑“默认”图像。子查询似乎没有做任何事情。

【问题讨论】:

    标签: mysql sql-order-by


    【解决方案1】:

    SQLFiddle demo

    select products.id,
           coalesce(t1.mid,t2.mid) as image_id      
    
    from products
    left join (select min(id) mid,product_id 
                      from images where `default`=1
                      group by product_id ) t1
            on products.id=t1.product_id
    left join (select min(id) mid,product_id 
                      from images where `default`=0
                      group by product_id ) t2
            on products.id=t2.product_id
    

    【讨论】:

    • 这个查询很慢。我对其进行了优化:sqlfiddle.com/#!2/4d948/6/0 但在我的测试中,当需要除 product_id 和 image_id 之外的任何列时,它仍然比我的查询慢。
    【解决方案2】:

    看起来我只是在子查询的 ORDER BY 中遗漏了一个“DESC”

    :\

    【讨论】:

      【解决方案3】:

      如果您只想为产品显示一张图片,请尝试此查询 -

      SELECT p.*, i.* FROM products p
        JOIN (SELECT * FROM images ORDER BY `default` DESC) i
          ON p.id = i.product_id
      GROUP BY p.id
      

      【讨论】:

        【解决方案4】:

        试试这个:

        SELECT 
          p.id productid, 
          IFNULL(i1.id, i2.id)
        FROM products    AS p
        LEFT JOIN images AS i1  ON p.id = i1.product_id
                               AND i1.`Default` = 1  
        LEFT JOIN images AS i2  ON p.id = i2.product_id
                               AND i2.`Default` = 0
        GROUP BY p.id;
        

        【讨论】:

        • 这会比我的查询更有效率吗?
        • @kryo 它总是取决于。但我认为你的会更好,因为它只涉及一个 JOIN。
        • 看起来与我的 13 个“样品”产品和 19 个“样品”图像差不多。猜猜我们会在它上线后决定......:D
        猜你喜欢
        • 1970-01-01
        • 2013-11-20
        • 2014-08-31
        • 2014-01-30
        • 2013-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多