1

我有两张桌子:TableA 和 TableB

表 A:columnBLA、objName、objID

表 B: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 知识并没有那么远。

4

2 回答 2

1

这是同时使用 anUNPIVOT和 a 的一种方法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从您的单独列获取值并将其转换为行。然后我将 arow_number()应用于数据,然后应用数据透视表将其转换回列。

不使用PIVOTandUNPIVOT函数的另一种方法是应用 arow_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

请参阅带有演示的 SQL Fiddle

两个查询的结果是:

| OBJID | STRINGVALUE | NUMBERVALUE | DATEVALUE |
-------------------------------------------------
|    21 |           a |          11 |  1/1/2012 |
|    21 |           b |          22 |  1/1/2013 |
|    21 |           c |          33 |  1/1/2014 |
于 2013-02-05T11:43:28.647 回答
0

使用CTErow_number()小提琴演示

;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
于 2013-02-05T13:33:45.220 回答