我有两个表:TableA和TableB
TableA:columnBLA,objName,objID
TableB:objID,ColumnIndex,StringValue,NumberValue,DateValue
TableA has a row: bla, Object Name, 21
TableB also has data for objID=21:
21, 1, a, NULL, NULL
21, 1, b, NULL, NULL
21, 1, c, NULL, NULL
21, 2, NULL, 11, NULL
21, 2, NULL, 22, NULL
21, 2, NULL, 33, NULL
21, 3, NULL, NULL, 1/1/2012
21, 3, NULL, NULL, 1/1/2013
21, 3, NULL, NULL, 1/1/2014
现在我想将这些数据重新整形为以下形式:
a, 11, 1/1/2012
b, 22, 1/1/2013
c, 33, 1/1/2014
我到目前为止:
Select StringValue, NumberValue, DateValue
From
(Select StringValue
From TableA ta WITH (NOLOCK), TableB tb WITH (NOLOCK)
WHERE ta.objID = tb.objID
AND t.objName = N'Object Name'
AND d.ColumnIndex = 1) As StringValues
,
(Select NumberValue
From TableA ta WITH (NOLOCK), TableB tb WITH (NOLOCK)
WHERE ta.objID = tb.objID
AND t.objName = N'Object Name'
AND d.ColumnIndex = 2) As NumberValues
,
(Select DateValue
From TableA ta WITH (NOLOCK), TableB tb WITH (NOLOCK)
WHERE ta.objID = tb.objID
AND t.objName = N'Object Name'
AND d.ColumnIndex = 1) As DateValues
但是我得到了不必要的结果。 有人告诉我,我应该使用PIVOT,但我的SQL知识并没有跨越那么远。
答案 0 :(得分:1)
以下是使用UNPIVOT
和PIVOT
执行此操作的一种方法:
select objid, stringvalue, numbervalue, datevalue
from
(
select objid, col, value,
row_number() over(partition by objid, col order by value) rn
from
(
select a.objid,
b.stringvalue,
b.numbervalue,
b.datevalue
from tablea a
left join tableb b
on a.objid = b.objid
) src
unpivot
(
value
for col in (stringvalue, numbervalue, datevalue)
) unpiv
) s
pivot
(
max(value)
for col in (stringvalue, numbervalue, datevalue)
) piv
见SQL Fiddle with Demo。 unpivot 从单独的列中获取值并将其转换为行。然后,我将row_number()
应用于数据,然后应用 pivot 将其重新转换为列。
在不使用PIVOT
和UNPIVOT
函数的情况下执行此操作的另一种方法是应用row_number()
,然后使用带有CASE
表达式的聚合函数:
select objid,
max(case when columnindex = 1 then stringvalue end) stringvalue,
max(case when columnindex = 2 then numbervalue end) numbervalue,
max(case when columnindex = 3 then datevalue end) datevalue
from
(
select a.objid,
b.stringvalue,
b.numbervalue,
b.datevalue,
b.columnindex,
row_number() over(partition by a.objid, b.columnindex
order by b.columnindex) rn
from tablea a
left join tableb b
on a.objid = b.objid
) src
group by objid, rn
两个查询的结果是:
| OBJID | STRINGVALUE | NUMBERVALUE | DATEVALUE |
-------------------------------------------------
| 21 | a | 11 | 1/1/2012 |
| 21 | b | 22 | 1/1/2013 |
| 21 | c | 33 | 1/1/2014 |
答案 1 :(得分:0)
使用CTE
和row_number()
。 Fiddle Demo
;with cte as (
select row_number() over (partition by columnIndex
order by StringValue, NumberValue, DateValue) rn,
StringValue, NumberValue, DateValue
from tableB tb join tableA ta on tb.objId = ta.objid
)
select t1.StringValue, t2.NumberValue, t3.DateValue
from cte t1 join cte t2 on t1.rn = t2.rn
join cte t3 on t1.rn = t3.rn
where not (t1.stringValue is null or t2.numberValue is null or t3.datevalue is null)
order by t1.stringValue