进一步过滤 SQL 结果
Posted
技术标签:
【中文标题】进一步过滤 SQL 结果【英文标题】:Further filter SQL results 【发布时间】:2011-02-08 23:03:44 【问题描述】:我有一个使用 SQL 2005 返回正确结果集的查询。如下:
选择 案子 当 convert(varchar(4),datepart(yyyy,bug.datecreated),101)+ 'Q' +convert(varchar(2),datepart(qq,bug.datecreated),101) = '1969 Q4' 然后 '2009 Q2' else convert(varchar(4),datepart(yyyy,bug.datecreated),101)+ 'Q' +convert(varchar(2),datepart(qq,bug.datecreated),101) 以 [季度] 结尾, bugtypes.bugtypename, 计数(bug.bugid)作为[总计] 从 bug 左外连接 bug.crntbugtypeid = bugtypes.bugtypeid 和 bug.projectid = bugtypes.projectid 在哪里 (bug.projectid = 44 和 bug.currentowner 在 (-1000000031,-1000000045) 和 (42,37,25,14) 中的 bug.crntplatformid) 要么 (bug.projectid = 44 和 bug.currentowner in (select memberid from groupmembers where projectid = 44 and groupid in (87,88)) 和 (42,37,25,14) 中的 bug.crntplatformid) 通过...分组 案子 当 convert(varchar(4),datepart(yyyy,bug.datecreated),101)+ 'Q' +convert(varchar(2),datepart(qq,bug.datecreated),101) = '1969 Q4' 然后 '2009 Q2' else convert(varchar(4),datepart(yyyy,bug.datecreated),101)+ 'Q' +convert(varchar(2),datepart(qq,bug.datecreated),101) 结尾, bugtypes.bugtypename 按 1,3 desc 订购它会生成一个很好地分组的年份和季度列表、一个关联的描述符以及按降序排列的事件计数。我想做的是进一步过滤它,使其仅显示每季度提交次数最多的 10 个事件。
我正在苦苦挣扎的是如何获取这个结果集并实现它。
【问题讨论】:
可能按第 3 列(总计)降序排序并添加一个类 WHERE ROWNUM 在哪里以及如何,我不想要只十条记录。我想要每个季度 10 条记录。 【参考方案1】:您已经按季度和总计订购。您是否尝试过使用:
SELECT TOP 10
.....查询的其余部分
编辑:阅读您的评论后,我意识到您需要使用 RANK and Partition 来完成这项工作。您可以如下所示包裹在 CTE 中:
;WITH IncidentsTable AS
(
... Insert Your Query here ...
)
SELECT * FROM
(
SELECT [Quarter],
BugTypeName,
Total,
Rank() OVER (Partition BY [Quarter] order by Total DESC) AS Ranking
FROM
IncidentsTable
)
WHERE
Ranking <= 10
ORDER BY
Quarter, Total;
【讨论】:
这只会返回 10 条记录,我想要每个季度的前 10 条记录。因此,如果有 15 个季度,我希望返回 150 条记录,每个记录前 10 条。 我喜欢这个结构,它比尝试将我的查询插入到 Alex K 中要干净一些。【参考方案2】:这样的模式可以做到(每个季度的分区和编号忽略数字
SELECT * FROM (
SELECT Qtr, fld,
ROW_NUMBER() OVER(PARTITION BY Qtr ORDER BY fld) as RN
FROM tbl
) AS T
WHERE RN <= 10
ORDER BY Qtr
NTILE(10)
可能也会这样做。
【讨论】:
这很接近,我用 Rank() 替换了 Row_Number() 并且它起作用了。【参考方案3】:你可以使用等级和分区
Select * From
(
Select *, Rank() over (Partition BY qtr order by qtr, id ) as Rank
From
(
Select 1 as id, 1 as qtr,'hello' as msg
union all select 2, 1,'hello'
union all select 3,1,'hello'
union all select 4,1,'hello'
union all select 5,1,'hello'
union all select 6,2,'hello'
union all select 7,2,'hello'
union all select 8,2,'hello'
union all select 9,2,'hello'
union all select 10,2,'hello'
) BaseQuery
)QryWithRank
where rank <= 2
【讨论】:
以上是关于进一步过滤 SQL 结果的主要内容,如果未能解决你的问题,请参考以下文章