问题是这样的,假如公司有10000人,公司的员工的薪水从500到10000不等,现在要以500为一个梯度,统计每个阶段的员工的人数
结果格式:
工资水平 人数
500~999 10
1000~1499 324
1500~2000 459
..... ...
9500~10000 33
我是初学者,希望能够讲的详细点。谢谢!
楼上的周强其实已经给出了解答的本质,跟着本质去写SQL语句是件很简单的问题,楼主应该多动动脑筋,同时多动动手,我给出自己在MS-SQL2000(注意产品的特定环境,其他数据库产品实现方式或许略有不同)下的完整模拟过程吧,就当我犯错误坑害“小老鼠”。
建表,插入相应测试数据
USE D_Salary
GO
CREATE TABLE T_EmpSalary
(
AutoID int IDENTITY(1,1) PRIMARY KEY,
EmpName nvarchar(20) NOT NULL,
Salary int NOT NULL
)
GO
USE D_Salary
GO
DECLARE @Index int,
@EmpName nvarchar(20),
@Salary int
SET @Index = 1;
SET @EmpName = 'rainnoless';
SET @Salary = 500;
WHILE @Index < 10001
BEGIN
INSERT INTO [D_Salary].[dbo].[T_EmpSalary]
(EmpName, Salary)
VALUES
(@EmpName, @Salary)
IF @@ERROR = 0
BEGIN
IF @Index BETWEEN 1 AND 9000
SET @Salary = 500 + @Index
ELSE
SET @Salary = @Index
SET @Index = @Index + 1;
SET @EmpName = 'rainnoless' + CAST(@Index AS VARCHAR(5));
CONTINUE
END
ELSE
BREAK
END
测试数据入库后,请自行将大小连续的数据做一些修改,否则出来的统计数据都是500……。
在真实的生产环境,对表建立相应索引是必须的,这里就不做复述了,因为如果建立索引这个不是一两句话能说清楚,需要自己去实践摸索吧。
最后给出你要的答案,利用一个派生表的查询,得到你需要的效果集:
SELECT ( CAST(MIN(minSalary) AS VARCHAR(5)) + '~' + CAST(MAX(maxSalary) AS VARCHAR(5)) ) AS SalaryBound, COUNT(Totals) AS Totals
FROM (SELECT MAX(Salary/500) AS Totals, MAX(Salary) AS maxSalary, MIN(Salary) AS minSalary
FROM [D_Salary].[dbo].[T_EmpSalary]
GROUP BY AutoID) AS SalaryTotals
GROUP BY Totals
ORDER BY MIN(minSalary)
在涉及到计算列的时候,我想把其中的派生表单独拿出来作为一个视图:
CREATE VIEW V_SalaryTotals
AS
SELECT MAX(Salary/500) AS Totals, MAX(Salary) AS maxSalary, MIN(Salary) AS minSalary
FROM [D_Salary].[dbo].[T_EmpSalary]
GROUP BY AutoID
GO
SELECT ( CAST(MIN(minSalary) AS VARCHAR(5)) + '~' + CAST(MAX(maxSalary) AS VARCHAR(5)) ) AS SalaryBound, COUNT(Totals) AS Totals
FROM [D_Salary].[dbo].[V_SalaryTotals]
GROUP BY Totals
ORDER BY MIN(minSalary)
给你一个ORACLE的写法
思路是一样的.
select count(1),(a*500)||'-'||( (a+1)*500-1) step from(
select id,salary, trunc(SALARY/500) a From woody
) group by a
很简单嘛,用工资/500 会得出0-20之间的整数,然后每个整数有多少个就可以了,然后这个整数*500就是工资区间。
declare @i int,@sql varchar(500)
select @i=0,@sql='select ''0~500'' as 工资水平,count(*) as 人数 from 员工薪水表 where 薪水 between 0 and 500'
set @i=500
while @i<10000
begin
set @sql=@sql+' Union select '''+CAST(@i as varchar)+'~'+CAST(@i+500 as varchar)+''', count(*) from 员工薪水表 where 薪水 between '+cast(@i as varchar)+' and '+cast(@i+500 as varchar)
set @i=@i+500
end
exec(@sql)
我这个简单些,拼接一个字符串就行了。