SQL Server GROUP BY和Filter Top 10%

时间:2016-03-01 19:08:55

标签: sql-server

我正在尝试构建第一个GROUP BY季度的查询,然后获得销售额的前10%。示例:如果我在GROUP BY季度,2007 Q1的结果应为4,175行,这意味着在经过10%计算后(脚本底部),我应该在2007年Q1获得417行。我之前的查询是正确分组,即2007年第一季度为4,174,但在前10%过滤器之后,我得到的错误值为263行。

我编辑了该查询以获得下面的查询。现在我收到以下错误:子查询返回的值超过1。当子查询遵循=,!=,<,< =,>,> =或子查询用作表达式时,不允许这样做。

编写此查询的正确方法是什么?

SELECT
      [quarter]
      ,[address]
      ,[aptmnt]
      ,[listed]
      ,[cs_date]
      ,[updted]
      ,[price]
      ,[totsqft]
      ,[rooms]
      ,[bdrms]
      ,[baths]
      ,[sect]
FROM [dbo].[top10salesbyyear] p1

 WHERE 

(SELECT COUNT(*)  FROM [dbo].[top10salesbyyear] p2 GROUP BY
     [quarter]
     ,[address]
     ,[aptmnt]
     ,[listed]
     ,[cs_date]
     ,[updted]
     ,[price]
     ,[totsqft]
     ,[rooms]
     ,[bdrms]
     ,[baths]
     ,[sect]

 HAVING p2.price >= p1.price)<=
   (SELECT 0.1 * COUNT(*) FROM [dbo].[top10salesbyyear])

2 个答案:

答案 0 :(得分:2)

我只想使用NTILE() window function

;WITH CTE as (
    SELECT *,
        NTILE(10) OVER (PARTITION BY quarter ORDER BY Price DESC) as NTILE
    FROM [dbo].[top10salesbyyear]
)
SELECT *
FROM CTE
WHERE NTILE = 1

答案 1 :(得分:1)

如果使用Windows函数

,则很简单
WITH CTE as (
      SELECT *,
             count(*) OVER (partition by quarter) as total_rows,
             row_number() OVER (partition by quarter order by price DESC) as rn 
      FROM [dbo].[top10salesbyyear]
)
SELECT *
FROM CTE
WHERE rn < total_row * 0.1