2011-03-24 86 views
3

我试图做一个SQL语句,给我最高的X记录,然后所有其他的总和。第一部分是容易...有没有办法做一些像SQL NOT top语句?

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

什么是好的是,如果我工会第二查询类似...

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

...的结果集,看起来像,

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

有什么办法可以在TOP上做NOT操作符的等价操作吗? (我知道我大概可以创建顶级X的临时表并使用它,但我更喜欢只是单个SQL语句的解决方案。)

+0

很好的答案生日快乐!我被所有的WITH关键字引起了循环,因为我从来没有见过它。可悲的是,我坚持使用SQL 2000.如果我知道这是一个因素,我会将它包含在我的问题中。我已经提出了所有合适的答案,因为他们为大多数人提供了有效的解决方案。 – 2011-03-24 18:20:07

回答

6
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) 
+0

+1比我的答案简单! – 2011-03-24 16:18:44

+1

+1'因为@Martin喜欢它......但如何设置ORDER BY以使“其他”作为最后一行结束? – 2011-03-24 16:20:59

+2

@Philip Kelley:按部门顺序添加'Dept <>'其他',然后SUM(销售)结束desc' – Andomar 2011-03-24 16:26:05

1

您可以使用联合来求和所有其他部门。公共表表达式使得这一点更可读:

; 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

3
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 
+0

我总是惊讶马丁能够迅速解决这些疑问。如果他在线,我甚至不会试图回答这些问题......他会比我写的更好的查询以5分钟的时间打败我。 – 2011-03-24 16:19:44

+0

@mfredrickson - 然后Quassnoi进来一个更简单的! – 2011-03-24 16:21:14

1
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

这很好,因为它可以在早期版本的sql server中工作。 – 2011-03-24 18:15:14