所以我有一张表,看起来像这样:
ID | parentID | name | typeID
---------------------------------------
1 | 2 | thing1 | 1
2 | 4 | region1 | 0
3 | 4 | region2 | 0
4 | NULL | region3 | 0
5 | 3 | foo1 | 2
5 | 3 | foo2 | 2
6 | 3 | bar1 | 3
我需要的是一个像这样的输出:
ID | region | thing | foo | bar
--------------------------------------------
1 | region1 | thing1 | NULL | NULL
2 | region2 | NULL | foo1 | bar1
3 | region2 | NULL | foo2 | NULL
4 | region3 | NULL | NULL | NULL
有了这个
Select ID,
(CASE WHEN [typeID] = 0 THEN [name] END) AS region,
(CASE WHEN [typeID] = 1 THEN [name] END) AS thing,
(CASE WHEN [typeID] = 3 THEN [name] END) AS foo,
(CASE WHEN [typeID] = 5 THEN [name] END) AS bar
FROM [my].[dbo].[foobarthingtable]
where type = 0 OR type = 1 OR type = 3 OR type = 5
我得到这个(逻辑上):
ID | region | thing | foo | bar
--------------------------------------------
1 | NULL | thing1 | NULL | NULL
2 | region1 | NULL | NULL | NULL
3 | region2 | NULL | NULL | NULL
4 | region3 | NULL | NULL | NULL
5 | NULL | NULL | foo1 | NULL
6 | NULL | NULL | foo2 | NULL
7 | NULL | NULL | NULL | bar1
如何在(父)区域的同一行中获得那些“foos”,“bars”和“things”?
JPA方式(CriteriaQuery
)也很不错,因为我必须在JSF页面上将其显示为概述。
THX
答案 0 :(得分:1)
现在您应该按ID
设置GROUP结果WITH CTE AS
(
Select
(case when [typeID]=0 then ID ELSE parentID END) as ID,
(CASE WHEN [typeID] = 0 THEN [name] END) AS region,
(CASE WHEN [typeID] = 1 THEN [name] END) AS thing,
(CASE WHEN [typeID] = 3 THEN [name] END) AS bar,
(CASE WHEN [typeID] = 2 THEN [name] END) AS foo
FROM foobarthingtable
where typeid in (0,1,3,2)
)
select id,
MAX(REGION) REGION,
MAX(THING) THING,
MAX(FOO) FOO,
MAX(BAR) BAR
from CTE group by id
答案 1 :(得分:1)
您可以尝试使用PIVOT声明
;WITH PivotData AS
(
SELECT
ISNULL(t2.name, t1.name) as ParentRegion, -- grouping column
t1.name, -- aggregation column
CASE t1.typeid
WHEN 1 THEN 'thing'
WHEN 2 THEN 'foo'
WHEN 3 THEN 'bar'
END as mycolumn -- spreading column
FROM foobarthingtable t1
LEFT JOIN foobarthingtable t2 ON t1.[parentID]=t2.id AND t2.typeID = 0
WHERE t1.typeID in (0,1,2,3,5)
)
SELECT ParentRegion, [thing], [foo], [bar]
FROM PivotData
PIVOT(MAX(name) FOR mycolumn IN ([thing], [foo], [bar]) ) AS P
ORDER BY ParentRegion;
答案 2 :(得分:1)
最后,我知道了
;With NumberSequence( Number ) as
(
Select 1 as Number
union all
Select Number + 1
from NumberSequence
where Number < 100
),
base_list AS (
SELECT
ISNULL(t2.name, t1.name) as Region,
t1.name,
t1.typeid
FROM foobarthingtable t1
LEFT JOIN foobarthingtable t2 ON t1.[parentID]=t2.id AND t2.typeID = 0
)
SELECT
ROW_NUMBER() OVER (ORDER BY reg_list.Region, reg_list.Number) as ID,
reg_list.Region AS region,
thing_list.name AS thing,
foo_list.name AS foo,
bar_list.name AS bar
FROM (
SELECT
t1.Region,
NumberSequence.Number
FROM (
SELECT DISTINCT
ISNULL(t2.name, t1.name) as Region
FROM foobarthingtable t1
LEFT JOIN foobarthingtable t2 ON t1.[parentID]=t2.id AND t2.typeID = 0
WHERE t1.typeID in (0,1,2,3,5)
) t1
CROSS JOIN NumberSequence
) as reg_list
LEFT JOIN (
SELECT
bl.Region, bl.name, ROW_NUMBER() OVER(ORDER BY bl.Region, bl.name) rn
FROM base_list bl
WHERE typeID =1
) thing_list ON thing_list.Region=reg_list.Region AND reg_list.number=thing_list.rn
LEFT JOIN (
SELECT
bl.Region, bl.name, ROW_NUMBER() OVER(ORDER BY bl.Region, bl.name) rn
FROM base_list bl
WHERE typeID =2
) foo_list ON foo_list.Region=reg_list.Region AND reg_list.number=foo_list.rn
LEFT JOIN (
SELECT
bl.Region, bl.name, ROW_NUMBER() OVER(ORDER BY bl.Region, bl.name) rn
FROM base_list bl
WHERE typeID =3
) bar_list ON bar_list.Region=reg_list.Region AND reg_list.number=bar_list.rn
WHERE thing_list.name is not null or foo_list.name IS NOT NULL OR bar_list.name IS NOT NULL OR reg_list.Number=1
ORDER BY reg_list.Region, reg_list.Number