2017-09-05 143 views
1

下面的查询的第一行:MySQL只显示特定领域

SELECT * 
    FROM productlist.pricelist_merchant 
    WHERE product_id <> '0' 
ORDER BY 
    product_id ASC, 
    qty = 0, 
    price ASC; 

返回:

Merchant|product_id|price |qty| 
Merch_A |3217  |44.30 |16 | 
Merch_Z |3217  |45.14 |2 | 
Merch_U |3217  |45.62 |16 | 
Merch_I |3217  |46.06 |16 | 
Merch_Q |3217  |48.98 |55 | 
Merch_B |3217  |39.58 |0 | 
Merch_T |3217  |45.97 |0 | 
Merch_M |3217  |46.40 |0 | 
Merch_L |3220  |105.84|1 | 
Merch_Z |3220  |147.00|3 | 
Merch_U |3220  |149.36|2 | 
Merch_A |3220  |149.99|2 | 
Merch_Q |3220  |153.53|90 | 
Merch_I |3220  |154.51|2 | 
Merch_T |3220  |157.41|4 | 
Merch_C |3220  |164.59|46 | 
Merch_M |3220  |136.10|0 | 
Merch_B |3220  |136.71|0 | 

这是完美的我。如果有可用数量,则product_id按价格排序。但我只需要product_id的第一行。我想这样:

Merchant|product_id|price |qty| 
Merch_A |3217  |44.30 |16 | 
Merch_L |3220  |105.84|1 | 

只有product_id的第一行对我感兴趣。有没有办法改变我的查询来实现这一目标?我尝试了很多陈述,并没有一个工作...

在此先感谢!

+0

在您的查询中添加LIMIT 1 –

+0

@AhmetKarabulut不,如果OP只需要来自整个查询的单个记录,那么只会添加“LIMIT 1”。如果需要来自多个团体的单个记录,它将不起作用。 –

+0

不是“GROUP BY”的工作。您不能使用“GROUP BY”选择行。 “GROUP BY”使用来自每个组的数据计算新行。在[类似问题](https://stackoverflow.com/q/12102200/4265352)上查看[此答案](https://stackoverflow.com/a/28090544/4265352)。 – axiac

回答

3

处理此查询的一种规范(和ANSI兼容)方法是将您的原始表加入子查询中,该子查询会查找与每种产品的最低价格相对应的记录。然后,只需在原始表上执行SELECT *即可获取这些匹配行的所有信息。

SELECT t1.* 
FROM pricelist_merchant t1 
INNER JOIN 
(
    SELECT 
     product_id, 
     MIN(CASE WHEN qty > 0 THEN price END) AS min_price_qty, 
     MIN(CASE WHEN qty = 0 THEN price END) AS min_price_no_qty 
    FROM pricelist_merchant 
    WHERE product_id <> '0' 
    GROUP BY product_id 
) t2 
    ON t1.product_id = t2.product_id AND 
     t1.price  = COALESCE(t2.min_price_qty, t2.min_price_no_qty) 
ORDER BY t1.product_id 

这里的技巧是计算最低价格,同时通过产品的聚集。第一个是非零数量记录的最低价格。除非不存在这样的记录,否则该值将在联接中使用,在这种情况下,查询回落到零数量记录的最低价格。

输出:

enter image description here

演示在这里:

Rextester

它可能无法加快t1(你的原始表)和t2之间的连接,派生表,在一个重要的方式。但是,我们当然可以尝试加快发现每个产品最低价格的子查询。添加一个综合指数product_idprice

CREATE INDEX idx ON pricelist_merchant (accountid, logindate); 

现在在子查询中的聚合应该执行得更快,因此整体的查询可能会提高。

+0

感谢您的回答!有没有办法加快查询?我发布的查询需要大约30秒的时间才能运行。你的陈述现在运行了44分钟,这对我来说没有问题,因为我只需要每天运行一次。我会尽快给你答复。 – Vidarrus

+0

@Vidarrus我认为你可以添加一个复合索引来加速这个查询。我不知道它能得到多快,但请试一试我的建议,让我们知道结果。 –

+0

我现在有你的查询结果。该指数加速了很多。但是你的查询并没有给我希望的结果,因为它没有检查产品的数量。在我的例子中,Merch_B将成为产品3217的选择商家,但它应该是Merch_A,因为Merch_A的价格最便宜且数量大于0.如果我将“WHERE qty>'0'”添加到您的声明中,它会起作用,但有时候有些商品没有任何商品可供选择,所以我想让商家选择最合适的价格。 – Vidarrus