选择不同产品的最低价格的整行

时间:2017-05-26 08:25:48

标签: mysql group-by

我有下表关于产品:

| id | name   | product_id | price | seller_id | discount_id |
--------------------------------------------------------------
| 1  | phone  | 11         | 400   | 7         | 19          |
| 2  | cpu    | 78         | 120   | 33        | 4           |
| 3  | phone  | 11         | 380   | 8         | 22          |
| 4  | phone  | 11         | 460   | 5         | 19          |
| 5  | memory | 80         | 45    | 12        | 16          |
| 6  | router | 98         | 115   | 7         | 16          |
| 7  | cpu    | 78         | 115   | 33        | 66          |

我需要以最低价格选择不同product_id的所有列。还要订购按价格 ASC 的结果。对于这个例子:

| id | name   | product_id | price | seller_id | discount_id |
--------------------------------------------------------------
| 5  | memory | 80         | 45    | 12        | 16          |
| 6  | router | 98         | 115   | 7         | 16          |
| 7  | cpu    | 78         | 115   | 33        | 66          |
| 3  | phone  | 11         | 380   | 8         | 22          |

使用 GROUP BY product_id min(price执行此操作时没有问题,但我还需要其他列({{1 }}& seller_id

  • MySQL版本:5.7.17
  • 的sql_mode = only_full_group_by
  • 表格是临时的(ENGINE = MEMORY),不能 JOIN 多次

如何从MySQL生成上述结果?

2 个答案:

答案 0 :(得分:2)

添加具有最低价格的子查询,并加入最低价格和产品。

SELECT id, name,product_id,price,seller_id,discount_id FROM t
JOIN
(SELECT tt.product_id,MIN(tt.price) minp FROM t as tt 
GROUP BY tt.product_id)x
ON x.product_id=t.product_id AND x.price = t.price

LIMIT的另一个选择

SELECT * FROM T WHERE EXISTS
(SELECT 1 FROM T as TT ORDER BY TT.price ASC LIMIT 1 
WHERE t.id= TT.id)

鉴于MEMORY引擎是如此限制,采取穴居人的方式

SELECT SUBSTRING_INDEX(GROUP_CONCAT(id ORDER BY price),',',1),
SUBSTRING_INDEX(GROUP_CONCAT(name ORDER BY price),',',1),
product_id,MIN(price),
SUBSTRING_INDEX(GROUP_CONCAT(seller_id ORDER BY price),',',1),
SUBSTRING_INDEX(GROUP_CONCAT(discount_id ORDER BY price),',',1) FROM t
GROUP BY product_id

答案 1 :(得分:0)

您可以自己加入表格(在product_id上)。作为连接条件添加left.price > right.price - 然后选择行,其中right.price为null,因为对于该连接,没有较低的权利价格,这意味着您拥有left的那个是最低的:

SELECT l.id, l.name, l.product_id, l.price, l.seller_id, l.discount_id 
FROM 
  products l
LEFT JOIN
  products r
on
  l.product_id = r.product_id AND l.price > r.price
WHERE
  isnull (r.price) -- that means: no cheaper price for this position.

中间结果(SELECT *WHERE)看起来像(缩短):

| l.id | l.name    | l.product_id | l.price | r.id | r.name   | r.product_id | r.price
| 3    | phone     | 11           | 380     | null | null     | null         | null 
| 4    | phone     | 11           | 460     | 3    | phone    | 3            | 380

侧节点:对于非常大的数据集,可能存在性能问题,因为组件的每个附加行都会添加多个结果行。即考虑另一部电话:

| l.id | l.name    | l.product_id | l.price | r.id | r.name   | r.product_id | r.price
| 3    | phone     | 11           | 380     | null | null     | null         | null 
| 4    | phone     | 11           | 460     | 3    | phone    | 3            | 380
| 5    | phone     | 11           | 500     | 3    | phone    | 3            | 380
| 5    | phone     | 11           | 500     | 4    | phone    | 3            | 460

因此,如果您希望在过去60天内获得每日更改的最低价格,那么仅仅为#34;那就是大量的行... ...(实际上60+59+58+...+2+1我认为,导致最昂贵的价格会产生59比较行等等)