时间:2016-08-31 20:17:50

标签: mysql

我有一个产品表,其中包含卖家可以销售的所有产品。它有两列作为主键; product_codeamount(基本上是产品重量)。

随着产品重量的变化,其价格会有所不同。有6种产品重量可供选择:0.5, 1, 1.5, 2, 2.5, 3。具有不同权重的产品的产品代码将是相同的。

示例数据:

product_code | product_quantity | amount | quantity
1234         | 6                | 0.5kg  | 0
1234         | 6                | 1.0kg  | 7
1234         | 6                | 1.5kg  | 8

我想显示所有产品,但每个product_code只显示一次。

SELECT  * FROM products where group by product_code

鉴于以上三行,此查询为我提供了三行中的第一行。

但是,我想要返回数量大于零的行(如果存在),否则任何行都可以。

我需要在查询中进行哪些修改才能实现此目的?

这是我的桌面结构:

Table structure

2 个答案:

答案 0 :(得分:1)

如果您希望每product_code行有一行quantity,则可以使用带有相关子查询的WHERE条件,该子查询按quantity排序并限制为一行。

SELECT p1.* 
FROM products p1
WHERE (p1.product_code, p1.amount) = (
    SELECT p2.product_code, p2.amount
    FROM products p2
    WHERE p2.product_code = p1.product_code
    ORDER BY p2.quantity DESC
    LIMIT 1
)

您需要使用主键作为条件。但是因为我们在子查询中有WHERE p2.product_code = p1.product_code,所以我们也可以将其重写为:

SELECT p1.* 
FROM products p1
WHERE p1.amount = (
    SELECT p2.amount
    FROM products p2
    WHERE p2.product_code = p1.product_code
    ORDER BY p2.quantity DESC
    LIMIT 1
)

现在MySQL应该能够缓存每个product_code的子查询结果。使用(product_code, quantity, amount)(product_code, quantity)上的索引,子查询应该执行得非常快。

为了保持结果的确定性,您可以扩展子查询的ORDER BY子句。如果具有相同product_code的两行具有相同的quantity并且您想要选择具有更大amount的行(由于它是主键的一部分而不能相等)使用

ORDER BY p2.quantity DESC, p2.amount DESC

答案 1 :(得分:0)

请记住,您正在使用非标准功能,即按非聚合列的子集进行分组,在这种情况下(不保证)为每个组返回第一行... < / p>

通过在零数量之前遇到非零数量的有序行集来执行该组:

SELECT * FROM (
  SELECT * FROM products
  ORDER BY quantity desc
) x
GROUP BY product_code

注意:您使用的实施方式就是这样,但不保证未来版本将继续以您希望的方式可靠地运行。

另外,根据documentation

  

从MySQL 5.7.5开始,默认的SQL模式包括ONLY_FULL_GROUP_BY

这意味着您的查询不会在5.7.5+上运行,除非您在安装后主动禁用ONLY_FULL_GROUP_BY

可靠且可移植的方法是使用子查询来查找所有需要的数量并加入其中。但是你有一个额外的复杂因素,即产品的数量并不是唯一的,所以你必须使用金额打破平局:

SELECT p.*
FROM products p
JOIN (SELECT p2.product_code, max_quantity, max(amount) max_amount
      FROM products p2
      JOIN (SELECT product_code, MAX(quantity) max_quantity
            FROM products
            GROUP BY product_code) q
        ON q.product_code = p2.product_code
        AND max_quantity = p2.quantity
      GROUP BY product_code, max_quantity) qa
  ON p.product_code = qa.product_code
  AND quantity = max_quantity
  AND amount = max_amount

第一个子查询找到最大数量(这是您想要的数据),然后下一个子查询找到具有该最大数量的所有行的最大数量(可能有多个行共享最大数量)。由于产品代码,数量和数量的组合是唯一的,因此使用这些值连接回表格会为您提供所需的行。

免责声明:代码可能无法编译或工作,因为它在我的手机上被翻阅(但它有合理的可能性)