跳过数据为NULL的重复卷起的行

时间:2016-07-28 13:31:27

标签: sql-server tsql

我想按职位创建组织层次结构的报告。层次结构有4个级别,位置始终是最后一个叶子,但路径不一定是4级。

例如:

公司>位置

公司>部分>部门>位置

我想得到人数。

declare @hierarchy table
(
    Company nvarchar(50),
    Section nvarchar(50),
    Department nvarchar(50),
    Unit nvarchar(50),
    Position nvarchar(50),
    Person nvarchar(50)
)

insert into @hierarchy values
('WD', 'Weapons', 'IT', 'officer', null, 'Wile E.'),
('ACME', 'Weapons', 'IT', 'Network', 'engineer', 'Brain'),
('ACME', 'Weapons', 'IT', 'Network', 'support', 'Pinky'),
('ACME', 'Weapons', 'IT', 'officer', null, 'Bugs'),
('ACME', 'Weapons', 'IT', 'officer', null, 'Elmer'),
('ACME', 'Weapons', 'IT', 'officer', null, 'Daffy'),
('ACME', 'Weapons', 'tech', null, null, 'Sylverster'),
('ACME', 'Anvils', 'officer', null, null, 'Road')

select Company, Section, Department, Unit, Position, count(Person) from @hierarchy
group by rollup(Company, Section, Department, Unit, Position)

在上面的示例中,我为WD(WD,Anvils,Officer,NULL,NULL)获得相同的3行,其中一行就足够了,因为单位和位置不适用。

但是,如果我在查询中添加distinct,我会得到一个看似很好的结果

select distinct Company, Section, Department, Unit, Position, count(Person) from @hierarchy
group by rollup(Company, Section, Department, Unit, Position)

我不知道的是,这只是一些黑客攻击而且我很幸运,或者它是否是解决此问题的正确方法?

2 个答案:

答案 0 :(得分:1)

让我们为每个级别添加GROUPING列:

SELECT 
    Company, 
    Section, 
    Department, 
    Unit, 
    Position, 
    GROUPING(Company) as Company, 
    GROUPING(Section) AS Section, 
    GROUPING(Department) AS Department,
    GROUPING(Unit) AS Unit,
    GROUPING(Position) AS Position,
    COUNT(*)
from @hierarchy
group by ROLLUP(Company, Section, Department, Unit, Position)

看看你的重复值:

Company    Section    Department Unit       Position   Company Section Department Unit Position 
---------- ---------- ---------- ---------- ---------- ------- ------- ---------- ---- -------- -----------
ACME       Anvils     officer    NULL       NULL       0       0       0          0    0        1
ACME       Anvils     officer    NULL       NULL       0       0       0          0    1        1
ACME       Anvils     officer    NULL       NULL       0       0       0          1    1        1
ACME       Anvils     NULL       NULL       NULL       0       0       1          1    1        1
ACME       Weapons    IT         Network    engineer   0       0       0          0    0        1
ACME       Weapons    IT         Network    support    0       0       0          0    0        1
ACME       Weapons    IT         Network    NULL       0       0       0          0    1        2
ACME       Weapons    IT         officer    NULL       0       0       0          0    0        3
ACME       Weapons    IT         officer    NULL       0       0       0          0    1        3
ACME       Weapons    IT         NULL       NULL       0       0       0          1    1        5
ACME       Weapons    tech       NULL       NULL       0       0       0          0    0        1
ACME       Weapons    tech       NULL       NULL       0       0       0          0    1        1
ACME       Weapons    tech       NULL       NULL       0       0       0          1    1        1
ACME       Weapons    NULL       NULL       NULL       0       0       1          1    1        6
ACME       NULL       NULL       NULL       NULL       0       1       1          1    1        7
WD         Weapons    IT         officer    NULL       0       0       0          0    0        1
WD         Weapons    IT         officer    NULL       0       0       0          0    1        1
WD         Weapons    IT         NULL       NULL       0       0       0          1    1        1
WD         Weapons    NULL       NULL       NULL       0       0       1          1    1        1
WD         NULL       NULL       NULL       NULL       0       1       1          1    1        1
NULL       NULL       NULL       NULL       NULL       1       1       1          1    1        8

(ACME,Anvils,官员)重复3次,但每次都是一个新的分组级别:按部门,部门和单位,按部门,单位和职位。它'因为我们使用group by中的所有列。但单位和位置的值为NULL

因此,您可以在查询中添加DISTINCT以获得列的唯一结果 - 这是正确的。

答案 1 :(得分:0)

你可以去一堆工会而不是汇总吗?

select 
concat(Company,' ',Section,' ',Department,' ',Unit,' ',Position) as Hierarchy,
Total
from (
    select   Company, Section, Department, Unit, Position, count(*) as total from @hierarchy 
    group by Company, Section, Department, Unit, Position
    union
    select   Company, Section, Department, Unit, null, count(*) from @hierarchy 
    group by Company, Section, Department, Unit
    union
    select   Company, Section, Department, null, null, count(*) from @hierarchy 
    group by Company, Section, Department
    union
    select   Company, Section, null, null, null, count(*) from @hierarchy 
    group by Company, Section
    union
    select   Company, null, null, null, null, count(*) from @hierarchy 
    group by Company
) q
order by Company, Section, Department, Unit, Position;

给出:

ACME                                7
ACME Anvils                         1
ACME Anvils officer                 1
ACME Weapons                        6
ACME Weapons IT                     5
ACME Weapons IT Network             2
ACME Weapons IT Network engineer    1
ACME Weapons IT Network support     1
ACME Weapons IT officer             3
ACME Weapons tech                   1
WD                                  1
WD Weapons                          1
WD Weapons IT                       1
WD Weapons IT officer               1