MySQL LEFT JOIN, GROUP BY and ORDER BY not working as required

前端 未结 4 1831
清歌不尽
清歌不尽 2020-12-16 17:18

I have a table

\'products\' => (\'product_id\', \'name\', \'description\') 

and a table

\'product_price\' => (\'pro         


        
相关标签:
4条回答
  • 2020-12-16 17:30

    This will give you the last updated price:

    select
      p.*, pp.price
    from
      products p,
      -- left join this if products may not have an entry in prodcuts_price
      -- and you would like to see a null price with the product
      join 
      (
          select 
            product_price_id, 
            max(date_updated) 
          from products_price
          group by product_price_id
       ) as pp_max
        on p.product_id = pp.product_id
      join products_price pp on 
        pp_max.prodcuts_price_id = pp.products_price_id
    
    0 讨论(0)
  • 2020-12-16 17:31

    It appears that it is impossible to use an ORDER BY on a GROUP BY summarisation. My fundamental logic is flawed. I will need to run the following subquery.

    SELECT `p`.*, `pp`.`price` FROM `products` `p` 
    LEFT JOIN (
        SELECT `price` FROM `product_price` ORDER BY `date_updated` DESC
    ) `pp` 
    ON `p`.`product_id` = `pp`.`product_id`
    GROUP BY `p`.`product_id`;
    

    This will take a performance hit but as it is the same subquery for each row it shouldn't be too bad.

    0 讨论(0)
  • 2020-12-16 17:32

    You need to set aliases properly I think and also set what you are joining on:

    SELECT p.*, pp.price 
    FROM products AS p 
    LEFT JOIN product_price AS pp
    ON pp.product_id = p.product_id 
    GROUP BY p.product_id 
    ORDER BY pp.date_updated DESC
    
    0 讨论(0)
  • 2020-12-16 17:39

    Mysqlism:

    SELECT p.*, MAX(pp.date_updated), pp.price 
    FROM products p 
    LEFT JOIN product_price pp ON pp.product_id = p.product_id
    GROUP BY p.product_id 
    

    Will work on some RDBMS:

    SELECT p.*, pp.date_updated, pp.price 
    FROM products p 
    LEFT JOIN product_price pp ON pp.product_id = p.product_id
    WHERE (p.product_id, pp.date_updated) 
    
       in (select product_id, max(date_updated) 
           from product_price 
           group by product_id)
    

    Will work on most RDBMS:

    SELECT p.*, pp.date_updated, pp.price 
    FROM products p 
    LEFT JOIN product_price pp ON pp.product_id = p.product_id
    
    WHERE EXISTS
    (
        select null -- inspired by Linq-to-SQL style :-)
        from product_price 
    
        WHERE product_id = p.product_id 
    
        group by product_id
    
        HAVING max(date_updated) = pp.date_updated
    )
    

    Will work on all RDBMS:

    SELECT p.*, pp.date_updated, pp.price 
    FROM products p 
    LEFT JOIN product_price pp ON pp.product_id = p.product_id
    
    LEFT JOIN 
    (
        select product_id, max(date_updated) as recent 
        from product_price 
        group by product_id
    ) AS latest 
    ON latest.product_id = p.product_id AND latest.recent = pp.date_updated
    

    And if nate c's code intent is to just get one row from product_price, no need to table-derive (i.e. join (select product_price_id, max(date_updated) from products_price) as pp_max), he might as well just simplify(i.e. no need to use the product_price_id surrogate primary key) it like the following:

    SELECT p.*, pp.date_updated, pp.price 
    FROM products p 
    LEFT JOIN product_price pp ON pp.product_id = p.product_id
    WHERE pp.date_updated = (select max(date_updated) from product_price)
    
    0 讨论(0)
提交回复
热议问题