众所周知,GROUP BY
每组产生一行。我想每组产生多行。例如,特定用例是为每个项目选择两种最便宜的产品。
对于该组中的两个或三个元素来说,这是微不足道的:
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));
(Select n rows per group in mysql)
但我正在寻找一个可以在每个组中显示n
行的查询,其中n
是任意大的。换句话说,每个组显示5
行的查询应该可以转换为每组显示7
行的查询,只需替换其中的一些常量。
我不受任何DBMS约束,因此我对任何DBMS上运行的任何解决方案感兴趣。如果它使用一些非标准语法就可以了。
答案 0 :(得分:3)
对于任何支持分析函数\窗函数的数据库,这都相对容易
select *
from (select type,
variety,
price,
rank() over ([partition by something]
order by price) rnk
from fruits) rank_subquery
where rnk <= 3
如果省略[partition by something]
,您将获得排名前三的行。如果您希望每个type
排名前三,那么您partition by type
函数中就会rank()
。
根据您要处理关系的方式,您可能希望使用dense_rank()
或row_number()
而不是rank()
。如果首先使用rank
将两行绑定,则下一行的rnk
为3,而rnk
的{{1}}为dense_rank
。在这两种情况下,两个绑定行的rnk
都为row_number
。rnk
会随意给两个绑定行中的一行rnk
为1,另一行为<input type="hidden" name="propHosp" value="0">
<input type="checkbox" name="propHosp" <? if($propHosp == "1") echo "checked='checked'"; ?> value="1">
2。
答案 1 :(得分:2)
为了节省任何寻找时间的人,在撰写本文时,显然这不起作用,因为https://dev.mysql.com/doc/refman/5.7/en/subquery-restrictions.html。
我从未成为相关子查询的粉丝,因为我看到的大多数用法通常都可以更简单地编写,但我认为这已经改变了......一点点。 (这适用于MySQL。)
SELECT `type`, `variety`, `price`
FROM `fruits` AS f2
WHERE `price` IN (
SELECT DISTINCT `price`
FROM `fruits` AS f1
WHERE f1.type = f2.type
ORDER BY `price` ASC
LIMIT X
)
;
其中X是您想要的“任意”值。
如果您知道在价格重复的情况下如何进一步限制,并且数据允许这样的限制......
SELECT `type`, `variety`, `price`
FROM `fruits` AS f2
WHERE (`price`, `other_identifying_criteria`) IN (
SELECT DISTINCT `price`, `other_identifying_criteria`
FROM `fruits` AS f1
WHERE f1.type = f2.type
ORDER BY `price` ASC, `other_identifying_criteria` [ASC|DESC]
LIMIT X
)
;
答案 2 :(得分:1)
&#34;每组最大N问题&#34;可以使用窗口函数轻松解决:
select type, variety, price
from (
select type, variety, price,
dense_rank() over (partition by type) order by price as rnk
from fruits
) t
where rnk <= 5;
答案 3 :(得分:1)
Windows功能仅适用于SQL Server 2012及更高版本。试试这个:
DECLARE @yourTable TABLE(Category VARCHAR(50), SubCategory VARCHAR(50), price INT)
INSERT INTO @yourTable
VALUES ('Meat','Steak',1),
('Meat','Chicken Wings',3),
('Meat','Lamb Chops',5);
DECLARE @n INT = 2;
SELECT DISTINCT Category,CA.SubCategory,CA.price
FROM @yourTable A
CROSS APPLY
(
SELECT TOP (@n) SubCategory,price
FROM @yourTable B
WHERE A.Category = B.Category
ORDER BY price DESC
) CA
每个类别中两个价格最高的子类别的结果:
Category SubCategory price
------------------------- ------------------------- -----------
Meat Chicken Wings 3
Meat Lamb Chops 5