【问题标题】:sql; percent distribution with counted valuessql;具有计数值的百分比分布
【发布时间】:2026-02-04 10:20:07
【问题描述】:

我有一张表(工资),工资按性别和职位分配。 我想显示我数据库中每个职位的性别结果加上总值。例如,对于第一个标题,我有以下代码:

select 'Female' as '____',
       count(gender) as Number,
       SUM(Salary) AS Total_Salary,
       MIN(salary) AS Min_salary,
       AVG(salary) AS Avg_Salary,
       MAX(salary) AS Max_Salary
from Salaries
where gender= 'Female'
  And Job_titel='Adm assistent'
union (
select 'Man' as '____',
       count(gender) as Number,
       SUM(Salary) AS Total_Salary,
       MIN(salary) AS Min_salary,
       AVG(salary) AS Avg_Salary,
       MAX(salary) AS Max_Salary
from Salaries
where gender= 'Man'
  AND Job_titel='Adm assistent')
union (
select 'Total' as '____',
       count(gender) as Number,
       SUM(Salary) AS Total_Salary,
       MIN(salary) AS Min_salary,
       AVG(salary) AS Avg_Salary,
       MAX(salary) AS Max_Salary
from Salaries
where Job_titel ='Adm assistent' )

表格:

  ____  Number Tot_Salaries Min_Salaries Avg_Salaries Max_Salaries
----------------------------------------------------------

Female    142      1 000 000          XXXXXX         XXXXXXX      XXXXXXX  
Male       18        300 000          XXXXXX         XXXXXXX      XXXXXXX
Total     160      1 300 000          XXXXXX         XXXXXXX      XXXXXXX
----------

现在我希望表格具有这样的性别分布百分比和薪水:

   ___  Number %_Gender Tot_Salaries %  Min_Salaries Avg_Salaries Max_Salaries

Female    142    89     1 000 000   77   XXXXXX      XXXXXXX     XXXXXXX  
Male       18    11       300 000   13   XXXXXX      XXXXXXX     XXXXXXX
Total     160   100     1 300 000   00   XXXXXX     XXXXXXX      XXXXXXX
----------

如何获得这两个分布值?我认为我的代码现在可能非常无效:-)我使用 MS sql server。

【问题讨论】:

  • 将数据转储到临时表中并计算百分比。

标签: sql sql-server count distribution percentage


【解决方案1】:

totalcount 和 totalsalary 可以使用 2 个声明变量

declare @totalgender  decimal(12,1)
declare @totalSalary  decimal(12,1)

select @totalgender=(select count(gender) as total from Salaries where Job_titel ='Adm assistent' )
select @totalSalary=(select SUM(Salary) as total from Salaries where Job_titel ='Adm assistent' )

select 'Female' as '____',
       count(Salaries.gender) as Number, cast(count(Salaries.gender) / @totalgender*100 as int),
       SUM(Salary) AS Total_Salary, cast(SUM(Salary) / @totalSalary*100 as int),
       MIN(salary) AS Min_salary,
       AVG(salary) AS Avg_Salary,
       MAX(salary) AS Max_Salary
from Salaries   
where gender= 'Female'
  And Job_titel='Adm assistent'
union (
select 'Man' as '____',
       count(gender) as Number, cast(count(Salaries.gender) / @totalgender*100  as int),
       SUM(Salary) AS Total_Salary, cast(SUM(Salary) / @totalSalary*100 as int),
       MIN(salary) AS Min_salary,
       AVG(salary) AS Avg_Salary,
       MAX(salary) AS Max_Salary
from Salaries
where gender= 'Man'
  AND Job_titel='Adm assistent')
union (
select 'Total' as '____',
       count(gender) as Number, cast(count(Salaries.gender) / @totalgender*100  as int),
       SUM(Salary) AS Total_Salary, cast(SUM(Salary) / @totalSalary*100 as int),
       MIN(salary) AS Min_salary,
       AVG(salary) AS Avg_Salary,
       MAX(salary) AS Max_Salary
from Salaries
where Job_titel ='Adm assistent' )

或使用 select (select Job_titel, cast(count(gender )as decimal(5,2)) as total from Salaries where Job_titel ='Adm assistent' group by Job_titel) stot 连接表

select 'Female' as '____',
       count(s.gender) as Number, max(stot.total),
          cast(count(s.gender)/max(stot.total)*100 as int),
       SUM(s.Salary) AS Total_Salary,  
       MIN(s.salary) AS Min_salary,
       AVG(s.salary) AS Avg_Salary,
       MAX(s.salary) AS Max_Salary
from Salaries s inner join 
    (select Job_titel, cast(count(gender )as decimal(5,2)) as total from Salaries where Job_titel ='Adm assistent'  group by Job_titel) stot 
    on s.Job_titel= stot.Job_titel 
where gender= 'Female'
  And s.Job_titel='Adm assistent'
union  
select 'Man' as '____',
       count(s.gender) as Number, max(stot.total),
          cast(count(s.gender)/max(stot.total)*100 as int),
       SUM(s.Salary) AS Total_Salary,  
       MIN(s.salary) AS Min_salary,
       AVG(s.salary) AS Avg_Salary,
       MAX(s.salary) AS Max_Salary
from Salaries s inner join 
    (select Job_titel, cast(count(gender )as decimal(5,2)) as total from Salaries where Job_titel ='Adm assistent'  group by Job_titel) stot 
    on s.Job_titel= stot.Job_titel 
where gender= 'Man'
  And s.Job_titel='Adm assistent'  
union  
select 'Total' as '____',
       count(s.gender) as Number, max(stot.total),
          cast(count(s.gender)/max(stot.total)*100 as int),
       SUM(s.Salary) AS Total_Salary,  
       MIN(s.salary) AS Min_salary,
       AVG(s.salary) AS Avg_Salary,
       MAX(s.salary) AS Max_Salary
from Salaries s inner join 
    (select Job_titel, cast(count(gender )as decimal(5,2)) as total from Salaries where Job_titel ='Adm assistent'  group by Job_titel) stot 
    on s.Job_titel= stot.Job_titel 
where S.Job_titel ='Adm assistent'  

【讨论】:

  • 谢谢。这几乎可以正常工作。但我没有得到它想要的真实,因为第三列不是我想要的,我错过了第 3 列的标题,我错过了总工资的女性/男性百分比分布,请参阅这个链接我用你的代码得到了什么; sqlfiddle.com/#!6/e72b9/1
  • 对于您的第一个示例,我给予您真正的信任。它可以工作到 99%。除了没有百分比分布的标题。非常感谢。
  • 你好。我再次检查,性别百分比值没有显示 100%。总数是的,但女性得到 66 %,男性得到 33 %,请查看此链接 sqlfiddle.com/#!6/7fde5/1 这当然与四舍五入有关,但你能告诉我如何纠正这个问题。
【解决方案2】:

这将更加优化。无需多次从 Salaries 表中查询。

SELECT Job_title,gender,
        count(gender) as Number,
       SUM(salary) AS Total_Salary,
       MIN(salary) AS Min_salary,
       AVG(salary) AS Avg_Salary,
       MAX(salary) AS Max_Salary
   INTO #t
FROM Salaries
WHERE Job_title ='Adm assistent'
GROUP BY Job_title, gender

SELECT t.Job_title, t.gender, t.Number, 
        CASE WHEN t2.tot_num = 0 THEN 0 ELSE  t.Number/CAST(t2.tot_num AS float) * 100 END as [pct_gender],
        t.Total_Salary, t.Min_salary, t.Avg_Salary, t.Max_Salary
FROM #t t
    INNER JOIN  (SELECT Job_title, SUM(Number) AS tot_num
                FROM #t
                GROUP BY Job_title) t2 
        ON t2.Job_title = t.Job_title 
UNION   
SELECT t.Job_title, 'Total', SUM( t.Number),    
        100 as [pct_gender],
        SUM(t.Total_Salary), SUM(t.Min_salary) , SUM(t.Avg_Salary), SUM( t.Max_Salary)
FROM #t t
GROUP BY t.Job_title
ORDER BY Job_title,Number

DROP TABLE #t

【讨论】:

  • 谢谢!性别的总值还可以。但是对于 Min,AVG,MAX 的工资就不对了。对于 AVG_Salaries Totalvalue 它应该计算整个人口,这里它只是总结了女性和男性的平均工资。 Min 和 Max totalvalues 相同;它应该以这种方式计算整个总体; Female_Min=10 000,Male_Min=25000,那么总数应为 10 000。然后我错过了女性和男性的总 Salaris 百分比分布,其方式与 prc_gender 相同。感谢您的帮助,我正在路上 :-) 如果您能帮我解决这个问题,我将不胜感激。