开发者

Is there a way to do something like SQL NOT top statement?

开发者 https://www.devze.com 2023-02-19 06:59 出处:网络
I\'m trying to make a SQL statement that gives me the top X records and then all sums all the others.The first part is easy...

I'm trying to make a SQL statement that gives me the top X records and then all sums all the others. The first part is easy...

select top 3 Department, Sum(sales) as TotalSales
from Sales
group by Department

What would be nice is if I union a second query something like...

select NOT top 3 "Others" as Department, Sum(sales) as TotalSales
from Sales
group by Department

... for a result set that looks like,

Department    TotalSales
-----------   -----------
Mens Clothes  120.00
Jewelry       113.00
Shoes          98.00
Others        312.00

Is there a way to do an equivalent to a NOT operator on a TOP? (I know I can probably make a temp table of the top X and work with that, but I'd p开发者_JAVA百科refer a solution that was just a single sql statement.)


WITH    q AS
        (
        SELECT  ROW_NUMBER() OVER (ORDER BY SUM(sales) DESC) rn,
                CASE
                WHEN ROW_NUMBER() OVER (ORDER BY SUM(sales) DESC) <= 3 THEN
                        department
                ELSE
                        'Others'
                END AS dept,
                SUM(sales) AS sales
        FROM    sales
        GROUP BY
                department
        )
SELECT  dept, SUM(sales)
FROM    q
GROUP BY
        dept
ORDER BY
        MAX(rn)


WITH cte
     As (SELECT Department,
                Sum(sales) as TotalSales
         from   Sales
         group  by Department),
     cte2
     AS (SELECT *,
                CASE
                  WHEN ROW_NUMBER() OVER (ORDER BY TotalSales DESC) <= 3 THEN
                  ROW_NUMBER() OVER (ORDER BY TotalSales DESC)
                  ELSE 4
                END AS Grp
         FROM   cte)
SELECT MAX(CASE
             WHEN Grp = 4 THEN 'Others'
             ELSE Department
           END)        AS Department,
       SUM(TotalSales) AS TotalSales
FROM   cte2
GROUP  BY Grp
ORDER  BY Grp  


You can use a union to sum all other departments. A common table expression makes this a little bit more readable:

; with Top3Sales as
        (
        select  top 3 Department
        ,       Sum(sales) as TotalSales
        from    Sales
        group by 
                Department
        order by 
                Sum(sales) desc
        )
select  Department
,       TotalSales
from    Top3Sales
union all
select  'Other'
,       SUM(Sales)
from    Sales
where   Department not in (select Department from Top3Sales)

Example at data.stackexchange.com.


SELECT TOP 3 Department, SUM(Sales) AS TotalSales
FROM   Sales
GROUP BY Department
UNION ALL
SELECT 'Others', SUM(s.Sales)
FROM   Sales s
WHERE  s.Department NOT IN
       (SELECT Department
        FROM   (SELECT TOP 3 Department, SUM(Sales)
                FROM   Sales
                GROUP BY Department) D)
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号