3

我有一个要制作的数据透视表的技巧问题:

我有一张桌子,看起来像:

id  table   object  name     type   nvarchar    date    int     bit  
1   1       2       name     1      tables      NULL    NULL    NULL  
2   1       2       name     1      columns     NULL    NULL    NULL  
3   1       2       name     1      datatypes   NULL    NULL    NULL  
4   1       2       name     1      _users      NULL    NULL    NULL  
1   1       3       active   3      NULL        NULL    NULL    1  
2   1       3       active   3      NULL        NULL    NULL    1  
3   1       3       active   3      NULL        NULL    NULL    1  
4   1       3       active   3      NULL        NULL    NULL    1  

输出应如下所示:

id   name       active   
1    tables     1  
2    columns    1  
3    datatypes  1  
4    _users     1  

根据“类型”,我应该将列中的正确数据放入其中,这些列的格式为 nvarchar、bit、datetime、int 等。

“id”是行 id,“name, active”来自 name 列,值来自 nvarchar、date、int 和 bit 列。

更新:nvarchar、date、int 和 bit(以及大多数其他 SQL 格式)等列实际上包含这种类型的数据。“type”列给出了哪一列包含要使用的数据,所以如果“type”是“1”,我想使用“nvarchar”如果“type”是“3”而不是我想使用“bit " 它包含了一点,而不是 nvarchar。在 Pivot 中,我希望在“活动”列下有位,如果我在示例中有第三列(名称),例如“activation_date”,我想看到第三列的值(类型 = 2)从日期柱子。

我迷路了,请帮忙

4

1 回答 1

2

Assuming there's only one not null column for each row:

with cte as (
    select
        id,
        name,
        coalesce(
            [nvarchar],
            convert(nvarchar(max), [date], 120),
            cast([int] as nvarchar(max)),
            cast([bit] as nvarchar(max))
        ) as value
    from Table1 as t
)
select
    id,
    max(case when [name] = 'name' then value end) as [name],
    max(case when [name] = 'active' then value end) as [active]
from cte
group by id

sql fiddle demo

But I must warn you, this types of database schema is not best way to use SQL.

If you want to do this dynamically without hardcoding columns:

declare @stmt nvarchar(max)

select @stmt =
   isnull(@stmt + ', ', '') +
   'max(case when [name] = ''' + name + ''' then value end) as ' + quotename([name])
from (select distinct [name] from Table1) as t

select @stmt = '
with cte as (
    select
        id,
        name,
        coalesce(
            [nvarchar],
            convert(nvarchar(max), [date], 120),
            cast([int] as nvarchar(max)),
            cast([bit] as nvarchar(max))
        ) as value
    from Table1 as t
)
select
    id, ' + @stmt + '
from cte
group by id
'

exec sp_executesql
    @stmt = @stmt

sql fiddle demo

If you have some Mapping table like this:

name       value
--------------------
name       nvarchar
active     bit

you can use this query:

declare @stmt nvarchar(max)

select @stmt =
   isnull(@stmt + ', ', '') +
   'max(case when [name] = ''' + name + ''' then [' + value + '] end) as ' + quotename([name])
from Mapping

select @stmt = '
select
    id, ' + @stmt + '
from Table1
group by id
'

exec sp_executesql
    @stmt = @stmt

sql fiddle demo

于 2013-09-17T12:38:13.500 回答