2011-04-17 65 views
0

我将如何构建一个查询,将某个百分比下的任何东西归类为Other?TSQL通过百分比查询将“其他”添加到GROUP

例如有:

Select Country, (COUNT(Country)*100/(Select COUNT(*) From Logs)) as Perc 
FROM Logs 
Group by Country 
HAVING (COUNT(Country)*100/(Select COUNT(*) From Logs)) > 5 
ORDER BY Perc DESC 

我怎么会添加一行“其他”,将一切都低于6%的总和?

回答

3

另一种方法

;WITH Logs(Country) AS 
(
SELECT TOP 10 'UK' FROM sys.objects UNION ALL 
SELECT TOP 10 'US' FROM sys.objects UNION ALL 
SELECT TOP 1 'Timbuktu' FROM sys.objects 
), 
GroupedLogs AS 
(
SELECT Country, 
     (COUNT(Country) * 100.0/(SELECT COUNT(*) FROM Logs)) AS Perc 
FROM Logs 
GROUP BY Country 
) 
SELECT CASE WHEN Perc<6 THEN 'Other' ELSE Country END AS Country, 
     SUM(Perc) AS Perc 
FROM GroupedLogs 
GROUP BY CASE WHEN Perc<6 THEN 'Other' ELSE Country END 
+0

非常“干净”的代码。剪下供将来使用。 – 2011-06-16 12:48:33

1

我认为你需要一个联盟。没测试过,但类似:

SELECT * FROM 
(
    Select 
     Country, 
     (COUNT(Country)*100/(Select COUNT(*) From Logs)) as Perc 
    FROM 
     Logs 
    Group by 
     Country 
    HAVING 
     (COUNT(Country)*100/(Select COUNT(*) From Logs)) >= 6  

    UNION 

    Select 
     'Other' as Country, 
     (COUNT(Country)*100/(Select COUNT(*) From Logs)) as Perc 
    FROM 
     Logs 
    HAVING 
     (COUNT(Country)*100/(Select COUNT(*) From Logs)) < 6 
) 
ORDER BY 
    Perc DESC 
0

或者试用以下线的东西。这里的百分比在CTE中计算:

DECLARE @countries TABLE (name varchar(16), hit INT); 


INSERT INTO @countries 
VALUES 
('UK',1), 
('UK',1), 
('UK',1), 
('UK',1), 
('UK',1), 
('UK',1), 
('UK',1), 
('UK',1), 
('UK',1), 
('UK',1), 
('FRA',1), 
('FRA',1), 
('FRA',1), 
('FRA',1), 
('FRA',1), 
('USA',1), 
('MEX',1); 

WITH MY_PERCENTAGES AS 
(
    SELECT name, 
       CAST(count(*) AS NUMERIC(5,2)) 
       /
       CAST(SUM(count(*)) OVER() AS NUMERIC(5,2)) * 100. 
      AS percentage 
    FROM @countries 
    GROUP BY name 
) 
SELECT 
    name, 
    SUM (percentage) AS percentages 
FROM 
(
    SELECT 
     CASE 
     WHEN percentage <6 THEN 
      'OTHER' 
     ELSE 
      name 
     END AS name, 
     percentage 
    FROM MY_PERCENTAGES 
) TMP 
GROUP BY name;