0

我有两个数据表

选项卡1

    -------------------------
    | ID1 | ID2 |  A    | B |
    |  1  |  8  |'John' | 9 |
    |  2  |  9  |'Smith'| 0 |

TAB2

   ------------------------------------------
   | NAME | ID1 | ID2 | VSTRING | VINT |ROOT|
   | 'C1' |  1  |  8  |  'R01'  | NULL | 'A'|
   | 'C1' |  1  |  8  |  'R02'  | NULL | 'B'|
   | 'C2' |  1  |  8  |   NULL  | 9991 | 'B'|
   | 'C1' |  2  |  9  |  'D02'  | NULL | 'B'|

我需要一个会产生的查询

选项卡3

    -------------------------------------
    | ID1 | ID2 |   A    |  C1   |  C2  | 
    |  1  |  8  | 'John' | 'R01' | 9991 | 
    |  2  |  9  | 'Smith'| 'D02' | NULL |

TAB1 包含用户和 ID。TAB2 包含动态结构中的列和值。如果一个单元格(参见 [TAB2.NAME = 'C1' 和 TAB2.ID1 = 1])有多个值,则应采用与 ROOT = 'A' 关联的值。

我唯一的问题是如何根据 ROOT 列获取正确的值。以下代码返回正确的 TAB3 结构,但值不正确。

select t.id1, t.id2, t.a,
    max(case when t2.name = 'C2' then t2.vint end) c2,
    max(case when t2.name = 'C1' then t2.vstring end) c1
from tab1 t
    left join tab2 t2 on t.id1 = t2.id1 and t.id2 = t2.id2 
group by t.id1, t.id2, t.a

理想情况下,我希望有一个没有子查询的查询。

我通过子查询设法做到了这一点,但解决方案太慢了。上面的例子是Pivot onjoined tables SQL Server的后续。(PS:真实模型几乎有100个动态列)

4

2 回答 2

0

戈登林诺夫你的回答是正确的,但我没有找到让它更有活力的方法。幸运的是,我找到了一个非常通用的解决方案。关键是将TAB1 与分组的TAB2 连接起来。

Select * from TAB2 A join 
   (Select ID1, ID2, MIN(ROOT), NAME from TAB2 
       group by ID2, ID1, NAME) B
   on A.ID1 = B.ID1 and B.ID2 = A.ID2 and A.NAME = B.NAME
于 2013-06-07T00:18:20.033 回答
0

听起来您只tab2需要name, id1. 该row_number()功能可以为您执行此操作。它为每个这样的组分配一个序列。对于您的查询,此序列从 where 的行(如果有)开始root = 'A'

完整的查询与您的类似,除了tab2被替换为子查询并且on条件略有修改:

select t.id1, t.id2, t.a,
    max(case when t2.name = 'C2' then t2.vint end) c2,
    max(case when t2.name = 'C1' then t2.vstring end) c1
from tab1 t left join
     (select t2.*,
             row_number() over (partition by name, id1
                                order by (case when root = 'A' then 1 else 0 end) desc
                               ) as seqnum
      from tab2 t2
     ) t2
     on t.id1 = t2.id1 and
        t.id2 = t2.id2 and
        t2.seqnum = 1
group by t.id1, t.id2, t.a
于 2013-06-06T01:00:54.000 回答