我正在尝试为我的游戏挑选网站, 分数存储在SQL中。 游戏存储每个人的事件分数,因此每个玩家自然会有倍数。 我试图为每个球员收集顶部。 目前我正在使用分组
/**
* Write a function that will take a string as input and output
* a boolean (true or false) that describes if the string has valid parens.
*
* Use Cases:
*
* "" -> false
*
* null -> false
*
* "()" -> true
*
* ")" -> false
*
* "(" -> false
*
* "(())" -> true
*
* "())(" -> false
*
* "()))" -> false
*
* ")(" -> false
*
* "()()" -> true
*/
public boolean validParen(String input) {
// implementation?
}
这很好,但是我想在网站上显示的信息中添加kill count。 我尝试将KillCount按部分添加到组中,但随后显示每个人的分数,因为每次尝试的杀戮计数都不同。
SELECT TOP(250) *
FROM
( SELECT CharName, CharType, MAX(Point) AS SCORE
FROM SOD2RecBySandurr
GROUP BY CharName, CharType) AS derivedtbl_1
WHERE CharName
NOT LIKE '\[GM\]%' ESCAPE '\'
AND SCORE NOT LIKE '0'
ORDER BY SCORE DESC
如何让它根据charname进行字符分组,但显示chartype和killcount, 如果我在选择中有killcount但在组中没有,那么它会抛出错误。
这个让我感到困惑:/我理解为什么它没有根据名称对它们进行分组(鉴于killcount不会与任何其他条目匹配)但我无法理解为什么它要求它在组中为选择功能。
编辑:
目前的结果是:
SELECT TOP(250) *
FROM
(SELECT CharName, CharType, KillCount, MAX(Point) AS SCORE
FROM SOD2RecBySandurr
GROUP BY CharName, CharType, KillCount) AS derivedtbl_1
WHERE CharName
NOT LIKE '\[GM\]%' ESCAPE '\'
AND SCORE NOT LIKE '0'
ORDER BY SCORE DESC
我想看的地方
Player A - SCORE 1 - Kills 1
Player A - SCORE 2 - Kills 2
Player A - SCORE 3 - Kills 3
Player B - SCORE 1 - Kills 1
我想按最高分数排序,但包括该分数的杀人数
答案 0 :(得分:1)
从我读到这个的方式来看,你想要在比赛中展示他们的顶级杀戮的前250名玩家?
首先,考虑使用OFFSET
/ FETCH
来限制所使用的资源,并允许客户端指定查询的分页。有一些限制,但您可以阅读MSDN的ORDER BY CLAUSE来自行决定。
MAX
您想要返回最佳得分手,因此也要保留范围内的最大杀伤力。根据您的会话范围(Map?Series?All-Time?),您可能需要使用SUM
和/或OVER PARTITION BY
子句{{1}不支持OVER
子句直接} / OFFSET
考虑一下如何对它们进行分组,并且不会破坏组中的任何数据。因此,这些列需要聚合函数来提供任何用途(大多数情况下)。
如果你只是想要前250名得分手和他们的顶级杀手,一个解决方案可能如下:
FETCH
SELECT *
FROM (SELECT CharName, CharType, MAX(KillCount) AS KillCount, MAX(Point) AS SCORE
FROM SOD2RecB
WHERE CharName NOT LIKE '\[GM\]%' ESCAPE '\'
-- AND Point NOT LIKE '0'
GROUP BY CharName, CharType
HAVING MAX(Point) > 0) as SRC
ORDER BY SCORE DESC
FETCH FIRST 250 ROWS ONLY
和WHERE
获取HAVING
个参数。 SARG
可能会根据因素运行更快的过滤组而不是行。但是,请考虑使用SQL Server
子句。
更新(请参阅评论部分)当我写这篇文章时,我非常疲惫,所以可能会有错误。希望能够理解这一要点,以便您能够正确识别您的业务需求:
但是,如果您希望返回与MAX(Point)相关的KillCount列,则上述查询将无法保证您所记录的此结果。
对于组,删除不在WHERE
中的列的关系。关于此主题的GROUP BY
上有很多帖子更详细,但基本上您需要使用子查询,以便SO
可以正确过滤返回的结果。
出于性能原因,存在简化算法的方法,但请注意将使用表扫描。表扫描不一定是坏的,但在每一行上运行完整的,未优化的查询会很糟糕,所以请考虑对查询的影响。
您可能会发现SQL Server
在大数据集上而不是CTE上更快,但验证所使用的方法是否使用必要的最小比较(布尔值比数字更快,这肯定比字符串的隐式转换更快数据类型)和SARGable,你可以。
对于此示例,我选择使用OUTER APPLY
而不是INNER JOIN
纯粹作为方法的示例。主要思想是将组(CharName + CharType)的一个值(点)与返回到集合的最大值进行比较。绝对要考虑比较的基数。
OUTER APPLY
答案 1 :(得分:0)
在使用@clifton_h的答案已有一段时间之后,我重新评估了这一点, 我想出了如何获得相应的击杀数来匹配玩家得分最高的那一行:
我正在使用的Clifton_h的答案是:
SELECT CharName, CharType, KillCount, SCORE
FROM (SELECT CharName, CharType, MAX(KillCount) AS KillCount, MAX(Point) AS SCORE
FROM db.dbo.table
GROUP BY CharName, CharType HAVING (MAX(Point) > 0)) AS SRC
WHERE CharName NOT LIKE '\[GM\]%' ESCAPE '\' ORDER BY SCORE DESC;
但是,这给了我最大杀手数,这不一定与该玩家的最高得分有关。 我所做的是一条select语句,其中在顶层select中指定killcount列:
SELECT TOP(250) CharName, CharType, (SELECT KillCount FROM db.dbo.table WHERE Point=Score), Score
FROM (SELECT CharName, CharType, MAX(Point) AS Score
FROM db.dbo.table
GROUP BY CharName, CharType HAVING (MAX(Point) > 0)) AS SRC
WHERE CharName NOT LIKE '\[GM\]%' ESCAPE '\' ORDER BY SCORE DESC;
这基本上只是给我杀死计数,该计数与较低聚合的相应结果对齐。
还担任过内部联接:
SELECT a.CharName, a.CharType, a.KillCount, a.Point
FROM db.dbo.table AS a
JOIN (SELECT CharName, CharType, MAX(Point) AS Score FROM db.dbo.table GROUP BY CharType, CharName HAVING (MAX(Point) > 0)) AS b
ON a.CharName = b.CharName AND a.CharType = b.CharType AND a.Point = b.Score ORDER BY Point DESC;