2012-04-06 182 views
3

的百分比我有了一个表中以下列的MSSQL表店:SQL查询来选择总

Storeid, NumEmployees 
1  125 
2  154 
3  10 
4  698 
5  54 
6  98 
7  87 
8  100 
9  58 
10  897 

有人可以帮助我的SQL查询产生顶部店(STOREID),有30%的员工(NumEmployees)?不使用SUM/OVER

SELECT s.storeid, s.numemployees 
FROM (SELECT SUM(numemployees) AS [tots] 
     FROM stores) AS t, 
     stores s 
WHERE CAST(numemployees AS DECIMAL(15, 5))/tots >= .3 
ORDER BY s.numemployees desc 

Working Demo

注意的是,在第二个版本,我决定不除以100乘以之前

+0

我曾尝试选择SUM(numemploees)..发现有30%,然后选择从那个数字开始。 – user1204195 2012-04-06 17:46:29

+1

我对你想要的有点困惑。你是否需要这些行,从storeid 1开始,直到总共达到30%?哪个会给你店1,2,3,4。或者你是否想要这些行,从拥有最多员工的商店开始,直到你有30%的工作?哪个会让你的商店10?或者所有有30%以上的商店?这会给你4和10. – Kevin 2012-04-06 18:36:45

回答

10
WITH cte 
    AS (SELECT storeid, 
       numemployees, 
       (numemployees * 100)/SUM(numemployees) OVER (PARTITION BY 1) 
       AS 
       percentofstores 
     FROM stores) 
SELECT * 
FROM cte 
WHERE percentofstores >= 30 
ORDER BY numemployees desc 

Working Demo

替代。这需要铸造小数否则它会隐式转换为int导致没有记录返回

另外我不完全清楚,你想要这个,但你可以添加TOP 1两个查询,它会限制结果只是在一个设有专卖店的最大#有超过30%

UPDATE

根据您的意见听起来套用Kevin

您想要的行,开始在商店最员工和工作,直到你至少有30%

这是困难的,因为它需要一个正在运行的百分比但其一个装箱问题这样做的工作。注意我已经包括另外两个测试案例(其中百分比恰好等于和它只是在上面两个组合)

Working Demo

DECLARE @percent DECIMAL (20, 16) 

SET @percent = 0.3 
--Other test values 
--SET @percent = 0.6992547128452433 
--SET @percent = 0.6992547128452434 

;WITH sums 
    AS (SELECT DISTINCT s.storeid, 
         s.numemployees, 
         s.numemployees + Coalesce(SUM(s2.numemployees) OVER ( 
                PARTITION 
                BY 
                s.numemployees), 0) 
         runningsum 
     FROM stores s 
       LEFT JOIN stores s2 
        ON s.numemployees < s2.numemployees), 
    percents 
    AS (SELECT storeid, 
       numemployees, 
       runningsum, 
       CAST(runningsum AS DECIMAL(15, 5))/tots.total 
       running_percent, 
       Row_number() OVER (ORDER BY runningsum, storeid) rn 
     FROM sums, 
       (SELECT SUM(numemployees) total 
       FROM stores) AS tots) 
SELECT p.storeID, 
     p.numemployees, 
     p.running_percent, 
     p.running_percent, 
     p.rn 
FROM percents p 
     CROSS JOIN (SELECT MAX(rn) rn 
        FROM percents 
        WHERE running_percent = @percent) exactpercent 

     LEFT JOIN (SELECT MAX(rn) rn 
        FROM percents 
        WHERE running_percent <= @percent) underpercent 
     ON p.rn <= underpercent.rn 
      OR (exactpercent.rn IS NULL 
        AND p.rn <= underpercent.rn + 1) 
WHERE 
     underpercent.rn is not null or p.rn = 1  
+0

这不工作。内部查询不会产生0%的存储 – user1204195 2012-04-06 17:53:16

+0

我的意思是。内部查询产生0作为每个记录的百分比商店的结果 – user1204195 2012-04-06 17:54:01

+0

嗯您在分割之前删除了“* 100”吗?如果你确实需要将其转换为小数点 – 2012-04-06 17:55:51