0

我有一张表,上面有员工姓名和他们的供应商经验。我必须用以下数据创建一个表

给我的数据就像

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

请帮我查询。

4

4 回答 4

5

您可以使用case 语句来获取排他范围的计数:

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 以标记开放式结束范围。

Sql Fiddle 在这里

更新:尝试解释。

以右括号开头with和结尾的第一部分称为CTE。有时它被称为是inline view因为它可以在同一个查询中多次使用,并且在某些情况下是可更新的。在这里,它用于为范围准备数据,并适当地命名为ranges. 此名称用于主查询。Val是范围的最大值,count_all如果范围没有上限(18+,更多,或者您希望调用它),则为 1。数据行通过union all进行组合。您可以仅在括号之间复制/粘贴部分并运行它以查看结果。

主体使用交叉连接experiences将表与范围连接起来。这将创建来自和的所有行的组合。对于行,将有 4 行,experiencesrangesd 11

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 来生成标题 - 如果它是一个,则输出more,否则使用上限值构造标题。第二个 case 语句使用 sum(1) 计数。由于聚合函数忽略空值,并且如果没有找到匹配项,则没有 else 的情况评估为空,因此检查 count_all 是否为真(意味着经验中的这一行在此范围内计数)或是否vendor experience小于或等于上限就足够了当前量程的量程值。在上面的示例中,第一个范围不计入 11,但将计入所有其余范围。

然后按 val 和 count_all 对结果进行分组。为了更好地了解它是如何工作的,您可以删除 group by 和 sum() 并在聚合之前查看数字。按 empname 排序,val 将有助于查看 [count] 的值如何根据每个员工的不同 val 而变化。

注意:我已尽我最大的努力以我目前的英语水平。如果您需要一个(或两个,或任意数量),请随时要求澄清。

于 2012-09-25T13:07:25.533 回答
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)]
于 2012-09-25T13:14:22.690 回答
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。

于 2012-09-25T13:19:14.100 回答
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子句按参数排序)。

于 2012-09-25T13:35:15.997 回答