对多个参数执行“SELECT TOP 5”的最简单方法是啥?
Posted
技术标签:
【中文标题】对多个参数执行“SELECT TOP 5”的最简单方法是啥?【英文标题】:What is the simplest way to do "SELECT TOP 5" for multiple parameters?对多个参数执行“SELECT TOP 5”的最简单方法是什么? 【发布时间】:2019-01-15 13:16:59 【问题描述】:我正在尝试在 LibreOffice Base / HSQLDB 中构建一个新数据库,据称它支持标准 SQL,但可能不如 SQL-server 或 Oracle 广泛。
我有一个分数表,其中参与者是俱乐部列表中的一个成员。我需要在团队动态的情况下生成“团队分数”,即它们由每个俱乐部的前 5 名得分组成。
到目前为止,我能够达到的最接近的是:
SELECT "Score", "ShootRecords"."ClubID" FROM "ShootRecords" WHERE "ShootRecords"."ClubID" = 0
UNION
SELECT "Score", "ShootRecords"."ClubID" FROM "ShootRecords" WHERE "ShootRecords"."ClubID" = 1
ORDER BY "Score" DESC
如果我在每个子查询的开头添加 TOP 5
限定符,它会报告为无效 SQL。
如果我将ORDER BY
子句移动到子查询中,它再次报告为无效SQL,但每个子查询都需要按这种方式排序,并且限制为TOP 5
否则结果错误。
我也看过这样的子查询:
SELECT "ClubID"
FROM "Clubs"
WHERE "Clubs"."ClubID" IN
(SELECT "ClubID"
FROM "Clubs", "ShootRecords"
WHERE "Clubs"."ClubID" = "ShootRecords"."ClubID"
)
但排序和子设置再次以错误的顺序完成,或者无效。
我希望看到的是这样的:
Score ClubID
------------------
300 0
299 0
280 0
200 0
190 0
310 1
290 1
277 1
等等
【问题讨论】:
应该很简单。请添加一些示例数据和预期结果。 您是否尝试在每个联合查询中添加ORDER BY "Score" DESC LIMIT 5
? (ref)。另外,我认为在这种情况下UNION ALL
会更好。
另外,TOP 5
不是标准 SQL。附加LIMIT 5
(这也不是标准的,但得到很好的支持)。
LIMIT 5
也不是标准 SQL; FETCH FIRST 5 ROWS
是。但是,是的,HSQLDB 想要LIMIT 5
。
出现平局怎么办?我猜是从绑定的成员中任意选择一个成员?
【参考方案1】:
为了使您自己的查询正常工作,您需要为每个部分查询添加一个 ORDER BY
(和 LIMIT
)子句。为此,请使用括号:
(
SELECT Score, ClubID
FROM ShootRecords
WHERE ShootRecords.ClubID = 0
ORDER BY Score DESC
LIMIT 5
)
UNION ALL
(
SELECT Score, ClubID
FROM ShootRecords
WHERE ShootRecords.ClubID = 1
ORDER BY Score DESC
LIMIT 5
)
ORDER BY ClubID, Score DESC;
顺便说一句,我是UNION ALL
。 UNION [DISTINCT]
是一种特殊的联合形式,可以去除重复项。
【讨论】:
就是这样 - 我第一次看到UNION
的示例,子查询周围有括号。其余的都很好,只是没有被解析为两个不同的查询。【参考方案2】:
每组 TOP n 查询通常使用分析函数解决,但 HSQLDB 不支持。
无论如何,进入前五名意味着只有不到五个更好。
select *
from shootrecords sr
where 5 >
(
select count(*)
from shootrecords better
where better.clubid = sr
and
( better.score > sr.score
or
(better.score = sr.score and better.memberid < sr.memberid) -- for the case of ties
)
)
order by clubid, score, memberid;
如果出现平局(多个成员得分相同)我必须任意选择成员。我先选择那些 ID 最低的。
【讨论】:
以上是关于对多个参数执行“SELECT TOP 5”的最简单方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
使用 std::ostream 打印可变参数包的最简单方法是啥?
linux中设计一个shell脚本程序可以接受命令行输入的参数执行相应的菜单命令