这是mySQL 产品表
+--------+-------+-----+
|Product | Price | Cat |
+--------+-------+-----+
| iPhone | 1 | 32 |
| Samsung| 2 | 32 |
| Dell | 1 | 21 |
| HP | 2 | 21 |
| RedMi | 3 | 32 |
| Acer | 3 | 21 |
+--------+-------+-----+
必填结果在每个类别中前2名最便宜:
+--------+-------+-----+
|Product | Price | Cat |
+--------+-------+-----+
| iPhone | 1 | 32 |
| Samsung| 2 | 32 |
| Dell | 1 | 21 |
| HP | 2 | 21 |
+--------+-------+-----+
我尝试过select * from products group by cat order by price
,但是它只返回第一个最便宜的产品。我需要最便宜的前2名。
答案 0 :(得分:2)
您可以使用变量来获取每个类别的产品排名:
SET @rn := 0;
SET @cat := 0;
SELECT product, price, cat FROM (
SELECT @rn := case
WHEN @cat = cat then @rn + 1
ELSE 1
END AS rn, product, price, cat,
@cat := cat
FROM products
ORDER BY cat, price
) t
WHERE rn <= 2
ORDER BY cat, rn
请参见demo。
对于MySQL 8.0+,有ROW_NUMBER()
:
SELECT product, price, cat
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY cat ORDER BY price) rn
FROM products
) t
WHERE rn <= 2
ORDER BY cat, rn
请参见demo。
结果:
| product | price | cat |
| ------- | ----- | --- |
| Dell | 1 | 21 |
| HP | 2 | 21 |
| iPhone | 1 | 32 |
| Samsung | 2 | 32 |
答案 1 :(得分:0)
select type, variety, price
from fruits
where price = (select min(price) from fruits as f where f.type = fruits.type)
or price = (select min(price) from fruits as f where f.type = fruits.type
and price > (select min(price) from fruits as f2 where f2.type = fruits.type));
+--------+----------+-------+
| type | variety | price |
+--------+----------+-------+
| apple | gala | 2.79 |
| apple | fuji | 0.24 |
| orange | valencia | 3.59 |
| orange | navel | 9.36 |
| pear | bradford | 6.05 |
| pear | bartlett | 2.14 |
| cherry | bing | 2.55 |
| cherry | chelan | 6.33 |
+--------+----------+-------+
答案 2 :(得分:0)
在@forpas答案下的评论中引用
您的SQL语法有错误;检查与您的MariaDB服务器版本相对应的手册以使用正确的语法 '((PARTITION BY –
您还可以尝试模拟
的结果SELECT product, price, cat
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY cat ORDER BY price) rn
FROM products
) t
WHERE rn <= 2
ORDER BY cat, rn
以下查询或多或少与您有关,因为您的MariaDB似乎不支持窗口功能。
但是尝试升级到不支持window的MariaDB版本 功能。
查询
SELECT
products1.Product
, products1.price
, products1.cat
FROM
products products1
LEFT JOIN
products products2
ON
products1.cat = products2.cat
AND
products1.price >= products2.price
GROUP BY
products1.Product
, products1.cat
, products1.price
HAVING
COUNT(*) <= 2
ORDER BY
products1.Product ASC
, products1.cat ASC
, products1.price ASC
结果
| Product | price | cat |
| ------- | ----- | --- |
| Dell | 1 | 21 |
| HP | 2 | 21 |
| iPhone | 1 | 32 |
| Samsung | 2 | 32 |
请参阅demo
注意:此查询需要
INDEX(Product, Cat, price), INDEX(Cat, price)
此索引要求可能有点过高,因为这会使索引文件比表文件大很多。假设Product | Price | Cat
是唯一的列。
如果产品在猫和价格组中是唯一的,您应该可以摆脱。
查询
SELECT
(SELECT
products_inner.Product
FROM
products products_inner
WHERE
products_inner.cat = products1.cat
AND
products_inner.price = products1.price
) AS "Product"
, products1.price
, products1.cat
FROM
products products1
LEFT JOIN
products products2
ON
products1.cat = products2.cat
AND
products1.price >= products2.price
GROUP BY
products1.cat
, products1.price
HAVING
COUNT(*) <= 2
ORDER BY
products1.cat ASC
, products1.price ASC
结果
| Product | price | cat |
| ------- | ----- | --- |
| Dell | 1 | 21 |
| HP | 2 | 21 |
| iPhone | 1 | 32 |
| Samsung | 2 | 32 |
请参阅demo
注意:该查询仅需
INDEX(Cat, price)
但是另一方面,它对分组记录使用了一个相关的子查询来获得可能无法优化的产品。
请注意,您也可以编写和使用较短的ANSI / ISO SQL 92标准查询,我完全忘记了offcource也可以与INDEX(Cat, price)
一起使用
SELECT
*
FROM
products products_outer
WHERE
2 <= (
SELECT
COUNT(*) FROM products products_inner
WHERE
products_inner.cat = products_outer.cat
AND
products_inner.price >= products_outer.price
)
;
结果
| Product | Price | Cat |
| ------- | ----- | --- |
| iPhone | 1 | 32 |
| Samsung | 2 | 32 |
| Dell | 1 | 21 |
| HP | 2 | 21 |
请参阅demo
无论如何,有很多道路通向罗马,现在找到正确的道路