2016-08-31 43 views
0

我有一个产品表,其中包含可以由卖家出售的所有产品。它有两列作为主键; 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 

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

SELECT * FROM products where group by product_code 

鉴于上述三行,这个查询给了我三个中的第一行。

但是,如果它们存在,我想要返回数量大于零的行,否则任何行都会执行。

在我的查询中需要做些什么修改才能实现?

这里是我的表结构:记住,您使用的是非标准的功能

Table structure

+1

你写的:“这有两列作为主键; product_code和product_weight“。在图像中我看到'product_code'和'amount'上的一个关键符号。 –

+0

@PaulSpiegel对不起,刚刚更新了我的问题。 –

回答

0

轴承,即由非聚合列的子集分组,在这种情况下(不保证)第1行返回的每个组...

通过在一个有序的行集之前零个批量遇到非零量执行组:

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 

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

免责声明:代码可能无法编译或工作,因为它是用拇指在我的手机上(但有一个合理的机会,将工作)如果你想每product_code一行最高quantity

+0

非常感谢,它工作。 –

+0

wou;你是否解释过我在查询中的x? –

+1

@ BOTJr。需要所有子查询被赋予一个别名(即使它没有被实际使用)的语法需要“x”,它可以是任何东西。如果它使代码更清晰,你可以将它命名为“ordered_by_quantity”之类的名称。但我总是使用“x”(除了它是代数中的默认变量名以外没有特别好的理由)。 – Bohemian

1

你可以将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)或只是​​子查询应该执行得非常快。

为了保持结果的确定性,您可以扩展子查询的ORDER BY子句。如果两行具有相同product_code具有相同quantity,你要挑一个具有较大amount(其中水湿相等,因为它是主键的一部分),然后使用

ORDER BY p2.quantity DESC, p2.amount DESC