如何从另一个表中获取此sql表?

时间:2011-08-16 05:55:32

标签: sql-server

有没有办法像:

id Name    value
--------------------
1  sex        m 
2  age        12
3  weight    200
4  height    200
5  rx         34

from a known table:

sex age weight height rx
--------------------------
m   12    200  200    34

如果我这样做:

Select
    [id] = ORDINAL_POSITION,
    [Name] = COLUMN_NAME
    from INFORMATION_SCHEMA.COLUMNS
    where TABLE_NAME = 'known'

我明白了:

   id Name    
    -----------
    1  sex     
    2  age     
    3  weight  
    4  height  
    5  rx      

如何更改查询以获取:

   id Name    value
    --------------------
    1  sex        m 
    2  age        12
    3  weight    200
    4  height    200
    5  rx         34

如果他们是2行:

sex age weight height rx
--------------------------
m   12    200  200    34
f   34    245  111    67


id Name    value
--------------------
1  sex        m 
2  age        12
3  weight    200
4  height    200
5  rx         34
6  sex        f 
7  age        34
8  weight    240
9  height    111
10 rx         67

----------------- EDIT --------------------

感谢您的回答,但我想知道这是否有可能获得

  id  value
    -------------------
    1  m
    2  12
    3  200
    4  200
    5  34

    from:

    sex age weight height rx
    --------------------------
    m   12    200  200    34

使用

 Select
[id] = ORDINAL_POSITION,
[Value] ...
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'known'

3 个答案:

答案 0 :(得分:0)

您可以使用PIVOT / UNPIVOT(请参阅联机丛书)。

答案 1 :(得分:0)

你可以试试这个。

declare @T table
(
  sex char(1),
  age int,
  weight int,
  height int,
  rx int
)

insert into @T values
('m',   12,    200,  200,    34),
('f',   34,    245,  111,    67)

select row_number() over(order by (select 1)) as ID,
       T2.X.value('local-name(.)', 'varchar(128)') as Name,
       T2.X.value('.', 'varchar(10)') as Value
from (select *
      from @T 
      for xml path(''), type
     ) as T1(X)
  cross apply T1.X.nodes('/*') as T2(X)

这部分order by (select 1)使得ID的分配有些不可预测。如果您按顺序使用主键(ID int identity)datetime,则可以将其更改为order by ID

答案 2 :(得分:0)

您将选择的任何方法遇到的问题是特定列中的所有数据必须属于同一类型。在你的情况下,你有性,这是一个字符,和一堆数字(可能是整数)。由于您无法使用UNPIVOT,这可以阻止您完整地执行此操作。但总有办法...

鉴于此设置代码:

CREATE TABLE test(sex char(1), age int, weight int, height int, rx int)
INSERT INTO test
SELECT 'm', 12 , 200, 200, 34
union select 'f',34,245,111,67

您可以这样做,这只是您查询的一小部分内容:

Select
[id] = ROW_NUMBER() OVER(ORDER BY isc.ORDINAL_POSITION),
[Name] = COLUMN_NAME,
[Value] = CASE LOWER(COLUMN_NAME)
            WHEN 'sex' THEN CAST(d.sex AS VARCHAR(20))
            WHEN 'age' then CAST(d.age AS VARCHAR(20))
            WHEN 'weight' THEN CAST(d.weight AS VARCHAR(20))
            WHEN 'height' THEN CAST(d.height AS VARCHAR(20))
            WHEN 'rx' THEN CAST(d.rx AS VARCHAR(20))
        END
from INFORMATION_SCHEMA.COLUMNS isc
CROSS JOIN dbo.test d
where TABLE_NAME = 'test'

输出:

1   sex m
2   sex f
3   age 12
4   age 34
5   weight  200
6   weight  245
7   height  200
8   height  111
9   rx  34
10  rx  67

您会注意到此输出与您自己的输出略有不同。这是因为您没有在“已知”表格中描述任何键。如果您在该表上有密钥,则只需更改此行:

[id] = ROW_NUMBER() OVER(ORDER BY isc.ORDINAL_POSITION),

[id] = ROW_NUMBER() OVER(ORDER BY d.yourKeyField, isc.ORDINAL_POSITION),