Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不带聚合的SQL pivot_Sql_Sql Server_Pivot - Fatal编程技术网

不带聚合的SQL pivot

不带聚合的SQL pivot,sql,sql-server,pivot,Sql,Sql Server,Pivot,更新 我已经修改了SQL FIDLE,以使部门名称更能反映我想要达到的目标。如果你看小提琴,有3个select语句 从数据中按正确顺序列出部门 这是我尝试旋转的结果 假选择,以便显示我想要达到的目标 在我的透视尝试的结果中,第二行显示departmentLevel1为空,departmentLevel3不应在此行中。我尝试了行数和分区的各种组合,但我似乎无法解决这个问题。完全沮丧 这是我最新的小提琴 在你投票结束之前 请阅读此问题,然后阅读问题的副本。所提出的问题要简单得多。我的问题不仅是关于数

更新

我已经修改了SQL FIDLE,以使部门名称更能反映我想要达到的目标。如果你看小提琴,有3个select语句

从数据中按正确顺序列出部门 这是我尝试旋转的结果 假选择,以便显示我想要达到的目标 在我的透视尝试的结果中,第二行显示departmentLevel1为空,departmentLevel3不应在此行中。我尝试了行数和分区的各种组合,但我似乎无法解决这个问题。完全沮丧

这是我最新的小提琴

在你投票结束之前 请阅读此问题,然后阅读问题的副本。所提出的问题要简单得多。我的问题不仅是关于数据透视,而且是对数据透视结果进行分组,并比数据透视的开始和停止时间做更多的事情。我想我们只是在看标题。如果你不想阅读整个问题,这是可以的,但不要假设它是与其他一些标题类似的问题相同,请

我意识到我必须有一个聚合,所以我尝试使用max,但我真的只是试图以更表格的方式显示这些信息,以便我可以将其加入到另一个数据集

以下是起始数据:

select  departmentID, departmentParentID, departmentName, departmentGroupSortBy, departmentLevel, sortBy
from    vDepartmentList
where   regionID = 3
order by departmentGroupSortBy, departmentLevel, sortBy

departmentID    departmentParentID  departmentName  departmentGroupSortBy   departmentLevel sortBy
---------------------------------------------------------------------------------------------------
111                                 neth test dept  1                       1                1
115             111                 test sub1       1                       2               1
112                                 test2           2                       1                2
113             112                 new sub2        2                       2               1
114             112                 new sub 3a      2                       2                 2
116             114                 should L3       2                       3                 1
如果我运行此查询:

select  departmentParentID, [1] as departmentLevel1, [2] as departmentLevel2, [3] as departmentLevel3
from    (
    select  departmentParentID, departmentLevel, departmentName
    from    vDepartmentList
    where   regionID = 3
    ) p
pivot (
    max(departmentName)
    for departmentLevel in ([1],[2],[3])
    ) as  pvt
order by departmentParentID
我得到这个结果:

departmentParentID  departmentLevel1    departmentLevel2    departmentLevel3
----------------------------------------------------------------------------
                    test2       
111                                     test sub1   
112                                     new sub2    
114                                                          should L3
但我想得到的是:

departmentParentID  departmentLevel1    departmentLevel2    departmentLevel3
----------------------------------------------------------------------------
111                 neth test dept      test sub1   
112                 test2               new sub2    
112                 test2               new sub 3a          should L3

有人对我的错误有什么建议吗?

旋转在某种程度上就像分组一样。您需要原始源中的一列作为分组依据。在这种情况下,您没有它,而且他不知道“testsub1”以任何方式连接到“neth test dept”。这里我们需要的是为层次结构建立根。我们可以用一个小的递归CTE将t替换为vDepartmentList:

;with x as (
    select *, departmentID as root
    from #t
    where departmentParentID is null
    union all
    select #t.*, x.root
    from #t
    inner join x on #t.departmentParentID = x.departmentID
)
select * 
from x
现在我们有一个根,还有另一个问题:我们只有两个根,但你想在结果中有三行。Pivot运算符将基本上分组到根列上,并将“new sub2”、“new Sub3A”和“should L3”视为都属于“test2”,并生成具有这些值各自最大值的单行

应该有区别的方法,但我在你的数据中看不到。看来,你运气不好。

我根据你的视图sql创建了下面的sql。你几乎可以在那里得到结果

我使用@temp table删除order by子句。也许您可以在实现中删除@temp表

请尝试以下sql:

declare @temp table
(
  id int identity,
  departmentLevel1 int,
  departmentLevel2 int,
  departmentLevel3 int,
  xRow int
)

insert into @temp 
select 
    d.lvl1, d.lvl2, d.lvl3
    ,Rrow
from
(
select 
    a.lvl1, a.lvl2, a.lvl3
    ,row_number() over(partition by a.lvl1,a.lvl2 order by a.lvl1,a.lvl2) as Rrow
    ,departmentGroupSortby, departmentlevel, sortby
from 
    vDepartmentList a
) d
where (d.lvl2 is not null) 
order by departmentGroupSortby, departmentlevel, sortby
;

select
    c.departmentLevel1 as departmentParentID
    ,Case
        when c.departmentLevel1 = d.departmentid then d.DepartmentName
        else 
            null
     end as DepartmentLevel1
    ,Case
        when c.departmentLevel2 = e.departmentid then e.DepartmentName
        else 
            null
     end as DepartmentLevel2
    ,Case
        when c.departmentLevel3 = f.departmentid then f.DepartmentName
        else 
            null
     end as DepartmentLevel3
    --,d.departmentId   ,e.departmentid ,f.departmentid
from
(
select 
    a.id, a.departmentLevel1,a.departmentLevel2,a.departmentLevel3
    ,a.xRow
from @temp a
inner join
(
select 
    cast(departmentLevel1 as nvarchar(5)) + cast(departmentLevel2 as nvarchar(5)) as xrow, count(cast(departmentLevel1 as nvarchar(5)) + cast(departmentLevel2 as nvarchar(5))) as xcount
from @temp
group by cast(departmentLevel1 as nvarchar(5)) + cast(departmentLevel2 as nvarchar(5))
) b on cast(a.departmentLevel1 as nvarchar(5)) + cast(a.departmentLevel2 as nvarchar(5)) = b.xrow and a.xRow = b.xcount
) c
left join department d on c.departmentLevel1 = d.departmentId
left join department e on c.departmentLevel2 = e.departmentid
left join department f on c.departmentLevel3 = f.departmentid
结果


希望这对您有所帮助

因为您需要返回层次结构数据结构的3个级别,所以使用联接而不是枢轴可能会更容易。首先返回父行:

select p.departmentName
from dbo.department p
where p.departmentParentID is null;
这将获得所有顶级行。然后,您开始为您需要的每个附加级别添加一个联接,在您的情况下,您总共需要三个级别,因此您将添加两个联接。最终查询将如下所示:

select p.departmentName department1,
    c.departmentName department2,
    gc.departmentName department3
from dbo.department p         -- parent level
left join dbo.department c    -- child level 
    on p.departmentID = c.departmentParentID
left join dbo.department gc   -- grandchild level
    on c.departmentID = gc.departmentParentID
where p.departmentParentID is null;

似乎使用联接而不是枢轴更容易得到结果。这将使用源数据,而不是您创建的递归视图。这产生了以下结果:

| DEPARTMENT1 | DEPARTMENT2 |  DEPARTMENT3 |
|-------------|-------------|--------------|
|     depart1 |     d1 sub1 |       (null) |
|     depart2 |      d2 sub |       (null) |
|     depart2 |     d2 sub2 | d2s2 subSub1 |
如果要使用递归查询获得结果,则可以稍微更改当前视图,以返回3列名称,而不是级别号:

;with cte as
(
    select departmentID, 
        departmentParentID,  
        departmentName as Department1,
        cast(null as varchar(100)) Department2,
        cast(null as varchar(100)) Department3,
        1 as Level
    from dbo.department
    where departmentParentID is null
    union all
    select d.departmentID, 
        d.departmentParentID,
        Department1,
        case when Level + 1 = 2 then d.departmentName else Department2 end,
        case when Level + 1 = 3 then d.departmentName else Department3 end,
        Level + 1
    from dbo.department d
    inner join cte h
        on d.departmentParentID = h.departmentID
)
select *
from cte;

看。然后,您可以使用WHERE子句进行一些筛选,以返回包含您需要的所有部门值的行

在子查询中使用row_number为parentid级别中的每个项创建唯一的值。这将允许返回多行。可能重复的行不是重复的行。部门级别的复杂性使其与简单地旋转开始和停止时间大不相同。也许这是我的问题的一部分,我试着去做很多事情once@bluefeet感谢您添加了一个行号,现在上面看到的结果至少显示了所有记录,但仍然没有将所有记录都放在正确的行上。我不知道如何正确地对这个结果进行分组。我对这个结果做了sql处理,因为我不容易解释。递归CTE是我试图改变观点的方式,但可能是我做错了。如果你有机会看看小提琴,看看我搞砸了什么,我很感激它。我投你一票,因为你是对的。我将为BlueFoots的简单性做一个标记。真棒@BlueFoots谢谢。我想我把注意力集中在一个复杂的问题上,真的需要退一步,从一个简单的方法来看待它。简单易行@兰斯:是的,当您最初发布它时,它似乎是一个简单的轴心,这就是为什么我建议使用行编号,但一旦您提供了其他详细信息,显然使用联接的查询将更容易
;with cte as
(
    select departmentID, 
        departmentParentID,  
        departmentName as Department1,
        cast(null as varchar(100)) Department2,
        cast(null as varchar(100)) Department3,
        1 as Level
    from dbo.department
    where departmentParentID is null
    union all
    select d.departmentID, 
        d.departmentParentID,
        Department1,
        case when Level + 1 = 2 then d.departmentName else Department2 end,
        case when Level + 1 = 3 then d.departmentName else Department3 end,
        Level + 1
    from dbo.department d
    inner join cte h
        on d.departmentParentID = h.departmentID
)
select *
from cte;