SQL 从至少有一个来自异性的表中获得前 3 名
Posted
技术标签:
【中文标题】SQL 从至少有一个来自异性的表中获得前 3 名【英文标题】:SQL to get top 3 from a table with at least one from opposite gender 【发布时间】:2018-03-29 23:15:34 【问题描述】:我有一个这样的数据库表
用户
id Capacity Gender
----------------------
1 10 M
---------------------
2 9 M
---------------------
3 4 F
---------------------
4 8 M
---------------------
5 7 F
---------------------
我想使用 SQL 检索按容量排序的前 3 条记录,其中至少有一条来自异性,如下所示
id Capacity Gender
----------------------
1 10 M
---------------------
2 9 M
---------------------
5 7 F
---------------------
由于我没有使用 oracle,因此我无法使用“分区方式”,我想要一个适用于 H2 数据库或与数据库无关的数据库(如果可能)。
提前致谢
山姆
【问题讨论】:
我删除了标签 sql,因为您的表格是 html 格式。真的是sql还是html? 对不起,我现在编辑了,我正在寻找sql解决方案。 在我看来,最简单的做法是选择性别 = M 的前 2 个和性别 = F 的前 2 个,然后选择其中的前 3 个。 谢谢我放回标签sql 【参考方案1】:这是相当长的,因为要求也很严格。 它正在利用自我加入和分组。 获取每个性别的前 2 名,以确保代表两个性别组。然后获得前三名。
SELECT id, capacity, gender
from (
SELECT t.id, t.gender, t.capacity,
COUNT(*) AS rn
FROM t
JOIN t AS t2
ON t2.gender = t.gender
AND ( t2.capacity > t.capacity
OR t2.capacity = t.capacity
AND t2.id <= t.id )
GROUP BY t.id, t.gender, t.capacity
HAVING COUNT(*) <= 2
ORDER BY t.capacity desc, rn ) tab
ORDER BY capacity desc
LIMIT 3;
Result:
id capacity gender
1 10 M
2 9 M
5 7 F
【讨论】:
这适用于 mysql、oracle 和 sqllite。对于 sqlserver,您可以放置 TOP 3 并删除 Limit 3。 顺便说一句,我没有 H2 的经验。 嗨,非常感谢,它适用于 H2 上的这个数据集。让我根据我的情况对其进行调整并进行更多测试。 如果可行,请点赞并接受我的回答。谢谢。【参考方案2】:这可能有点老套,但我相信它适用于您的问题。请尝试:
CREATE TABLE temp as
Select top 2 id, Gender, max(capacity) as maxcap
from table
where Gender ='F'
group by id, Gender
CREATE TABLE temp2 as
Select top 2 id, Gender, max(capacity) as maxcap
from table
where Gender ='M'
group by id, Gender
select top 3 id, gender, maxcap
from
(
Select id, Gender, maxcap
from temp
union
Select Gender, maxcap
from temp2
) t
order by t.maxcap desc
【讨论】:
我认为您也需要订购 temp 和 temp2。那里的 max() 和组没有添加任何东西,所以你总是得到前两条记录。如果您可以将其作为 CTE 执行此操作会更整洁,因为 H2 从外观上看不支持每个连接的临时表。 嗨,Eray,感谢您的想法。我想在不使用临时表的情况下在单个 sql 语句中执行此操作。山姆【参考方案3】:这是一个 CTE 答案,基于大卫康拉德的 cmets 方法:
with f(id, gender, capacity) as (select top 2 id, gender, capacity from capacity
where gender = 'F' order by capacity desc),
m(id, gender, capacity) as (select top 2 id, gender, capacity from capacity
where gender = 'M' order by capacity desc),
combined(id, gender, capacity) as (select * from f union select * from m)
select top 3 * from combined order by capacity desc;
(假设该表也称为“容量”)。如果没有 RANK() 函数,我看不出如何做得更好,而且我对 subquery count rank function suggested here 在大桌子上的表现感到紧张,如果你也走这条路,你必须小心平局.在 H2 和 SQL Server 上测试。
【讨论】:
以上是关于SQL 从至少有一个来自异性的表中获得前 3 名的主要内容,如果未能解决你的问题,请参考以下文章
在pl/sql中怎么查询所有存在的表,以及怎么样获得未知表中的某一字段