我有一张包含员工姓名及其供应商经历的表格。 我必须创建一个包含以下数据的表
给我的数据就像
empname vendor experience
a 1
b 2
c 10
d 11
e 20
f 12
g 21
h 22
我想生成一个SQL查询来显示像这样的数据
vendor_experience(months) count
0-6 2
0-12 5
0-18 5
more 8
请帮我查询。
答案 0 :(得分:5)
您可以使用case statement来获取排他范围的计数:
select case when [vendor experience] <= 6 then '0-6'
when [vendor experience] <= 12 then '0-12'
when [vendor experience] <= 18 then '0-18'
else 'more'
end [vendor_experience(months)],
count (*) [count]
from experiences
group by
case when [vendor experience] <= 6 then '0-6'
when [vendor experience] <= 12 then '0-12'
when [vendor experience] <= 18 then '0-18'
else 'more'
end
这会产生与您相同的结果(包含范围):
; with ranges as
(
select 6 as val, 0 as count_all
union all
select 12, 0
union all
select 18, 0
union all
select 0, 1
)
select case when ranges.count_all = 1
then 'more'
else '0-' + convert (varchar(10), ranges.val)
end [vendor_experience(months)],
sum (case when ranges.count_all = 1
or experiences.[vendor experience] <= ranges.val
then 1 end) [count]
from experiences
cross join ranges
group by ranges.val, ranges.count_all
count_all
设置为1以标记开放结束范围。
更新:尝试解释。
以with
开头并以右括号结尾的第一部分称为CTE。有时它被称为inline view
,因为它可以在同一查询中多次使用,并且在某些情况下是可更新的。这里它用于为范围准备数据,并且适当地命名为ranges
。此名称用于主查询。 Val
是范围的最大值,如果范围没有上端(18 +,更多,或者您希望调用它),则count_all
为1。数据行通过union all组合。您可以仅在括号之间复制/粘贴部分,并仅运行它以查看结果。
主体使用cross join将experiences
表与范围连接起来。这会创建experiences
和ranges
的所有行的组合。对于行d 11
,将有4行,
empname vendor experience val count_all
d 11 6 0
d 11 12 0
d 11 18 0
d 11 0 1
选择列表中的第一个case语句通过检查count_all生成标题 - 如果是1,则输出more
,否则使用高范围值构造标题。第二个案例陈述使用sum(1)计数。由于聚合函数忽略空值,并且如果未找到匹配,则没有其他情况评估为null的情况,只需检查count_all是否为真(意味着经验中的这一行在此范围内计算)或vendor experience
是否为{}小于或等于当前范围的上限值。在上面的例子中,第一个范围不计算11,但是将计算所有其余范围。
然后按val和count_all对结果进行分组。为了更好地了解它是如何工作的,您可以删除group by和sum()并在聚合之前查看数字。按empname排序,val将有助于查看[count]的值如何根据员工的不同val变化。
注意:我用我目前的英语水平做到了最好。如果您需要一个(或两个,或您需要的多个),请不要犹豫要求澄清。
答案 1 :(得分:0)
试试这个:
INSERT INTO ResultTable ([vendor_experience(months)], count)
Select *FROM
(
(SELECT '0-6', Count(*) From TableA WHERE [vendor experience] <= 6
UNION ALL
SELECT '0-12', Count(*) From TableA WHERE [vendor experience] <= 12
UNION ALL
SELECT '0-18', Count(*) From TableA WHERE [vendor experience] <= 18
UNION ALL
SELECT 'more', Count(*) From TableA) as Temp
)
如果不需要重复计数,请尝试以下操作:
select t.[vendor_experience(months)], count(*) as count
from (
select case
when [vendor experience] between 0 and 6 then ' 0-6'
when [vendor experience] between 7 and 12 then '0-12'
when [vendor experience] between 13 and 18 then '0-18'
when [vendor experience] >= 19 then 'more'
else 'other' end as [vendor_experience(months)]
from TableA) t
group by t.[vendor_experience(months)]
答案 2 :(得分:0)
更动态,为分组实现一个表:
create table #t (name varchar(10),e int)
insert into #t values ('a',0)
insert into #t values ('b',4)
insert into #t values ('c',3)
insert into #t values ('d',13)
insert into #t values ('e',25)
insert into #t values ('f',4)
insert into #t values ('g',19)
insert into #t values ('h',15)
insert into #t values ('i',7)
create table #g (t int, n varchar(10))
insert into #g values (6, '0-6')
insert into #g values (12, '0-12')
insert into #g values (18, '0-18')
insert into #g values (99999, 'more')
select #g.n
,COUNT(*)
from #g
inner join #t on #t.e <= #g.t
group by #g.n
例如,您可能想要使用值99999。
答案 3 :(得分:0)
以下是获取累积值的方法:
select sum(mon0_6) as mon0_6, sum(mon0_12) as mon0_12, sum(mon0_18) as mon0_18,
sum(more) as more
from (select e.*,
(case when [vendor experience] <= 6 then 1 else 0 end) as mon0_6,
(case when [vendor experience] <= 12 then 1 else 0 end) as mon0_12,
(case when [vendor experience] <= 18 then 1 else 0 end) as mon0_18,
1 as more
) e
这将它们放在不同的列中。然后,您可以使用unpivot
将它们放在不同的行中。
但是,您可以考虑在应用程序层执行累积求和。我经常在Excel中做这类事情。
在SQL Server 2008中执行累积求和需要显式或通过相关子查询进行自联接。 SQL Server 2012支持更简单的累积和语法(over
子句按参数排序)。