Groupby MySQL在使用排序时显示不同的记录

时间:2019-01-07 07:02:50

标签: mysql group-by

当我使用以下sql运行查询

SELECT 
userproduct_id,product_id,offer_price
FROM `tbluserproducts`
WHERE `product_id` = '4722'
ORDER BY `offer_price` asc

它显示这样的结果

userproduct_id  product_id  offer_price
4848            4722        1200
4835            4722        12500
4837            4722        12500
4841            4722        17000

以及在上述sql中添加groupby product_id时

SELECT 
userproduct_id,product_id,offer_price
FROM `tbluserproducts`
WHERE `product_id` = '4722'
group by product_id
ORDER BY `offer_price` asc

它仅显示一条记录

userproduct_id  product_id  offer_price
4835            4722        12500

但是它不显示userproduct_id 4848记录,因为我正在按offer price asc订购

我的表格结构如下

Column          Type                 
userproduct_id  int(10) unsigned Auto Increment 
product_id      int(11) unsigned    
offer_price     decimal(30,0)

2 个答案:

答案 0 :(得分:1)

您可以在下面尝试-

    SELECT 
    userproduct_id,product_id,offer_price
    FROM `tbluserproducts`
    WHERE `product_id` = '4722' and userproduct_id=(select max(userproduct_id)
from `tbluserproducts` b where b.`product_id` = '4722')

答案 1 :(得分:1)

使用GROUP BY时,查询将为product_id 4722返回一行。如果组中有多行,则MySQL从该行集中选择一行。

如何选择行?

它必须以某种顺序读取行,并选择读取的第一行。它在此查询中按PRIMARY KEY顺序读取行,因此显示的行中userproduct_id最少。

您提供的ORDER BY适用于之后 GROUP BY将输出减少到一行,因此它对一组一行进行排序,这没有效果。


我认为您想返回offer_price最少的行,对吗?您本可以在问题中更清楚地说明这一点。

基本上,这是在Stack Overflow上问过数百次的同类问题。标签用于此一般类型的问题。

在查询中,您仅选择一个product_id,因此使用LIMIT仅返回第一行将很容易。

SELECT 
  userproduct_id, product_id, offer_price
FROM `tbluserproducts`
WHERE `product_id` = '4722'
ORDER BY `offer_price` asc
LIMIT 1

如果您想要许多product_id,并且每个都有最低的offer_price行,则要复杂一些。在MySQL 8.0中,您可以使用窗口功能:

WITH ranked_userproducts AS (
  SELECT 
    userproduct_id, product_id, offer_price,
    ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY offer_price) AS rownum
  FROM `tbluserproducts`
)
SELECT 
  userproduct_id, product_id, offer_price
FROM ranked_userproducts
WHERE rownum = 1;

在MySQL 5.x中,您可以尝试另一种方法:

SELECT 
  userproduct_id, product_id, offer_price
FROM `tbluserproducts` AS p1
JOIN (
  SELECT product_id, MIN(offer_price) AS offer_price
  GROUP BY product_id ORDER BY NULL
) AS p2
  ON p1.product_id = p2.product_id AND p1.offer_price = p2.offer_price;

可能还有其他解决方案。我建议您遵循标签并阅读其他答案。