我要求将行值转换为列,但我试图删除空行并仅显示数据
declare @t table (id int,keys varchar(10),val varchar(10))
insert into @t (id,keys,val)values (1,'name','hulk'),(2,'age','22'),(3,'name','ironman'),(4,'age','35')
;with CTE AS (
Select [name],CAST([age] AS INT)age from (
select id,keys,val from @t )t
PIVOT(MAX(val) for KEYS in ([name],[age]))P
GROUP BY [name],age)
Select (C.name),(C.AGE) from CTE C
LEFT JOIN CTE cc ON c.age = cc.age AND c.name = cc.name
结果:
name AGE
NULL 22
NULL 35
hulk NULL
ironman NULL
期望的结果集:
name AGE
hulk 22
ironman 35
答案 0 :(得分:2)
您的数据结构存在很大缺陷,因为它没有人身份。
如果您认为"名称"开始每条记录,你可以做些什么:
select max(case when keys = 'name' then val end) as name,
max(case when keys = 'age' then val end) as age
from (select t.*,
sum(case when keys = 'name' then 1 else 0 end) over (order by id) as numnames
from @t t
) t
group by numnames;
这非常依赖于id
对记录顺序进行编码的事实(如示例数据中所示)。如果可能的话,我建议您添加另一个标识符。
编辑:
2012版之前的SQL Server中的等效查询:
select max(case when keys = 'name' then val end) as name,
max(case when keys = 'age' then val end) as age
from (select t.*, tt.numnames
from @t t cross apply
(select count(*) as numnames
from @t t2
where t2.id <= t.id and t2.keys = 'name'
) tt
) t
group by numnames;
答案 1 :(得分:2)
我同意戈登的看法,数据结构存在缺陷。但是,如果您始终假定年龄密钥ID遵循名称密钥ID 1,则以下操作将起作用。但是,如果你可以改变表结构,那就更好了..
declare @t table (id int,keys varchar(10),val varchar(10))
insert into @t (id,keys,val)
values (1,'name','hulk'),(2,'age','22'),(3,'name','ironman'),(4,'age','35')
select nc.id,nc.val as Name,xx.age
from @t nc
join (select id,val as Age from @t where keys='age') xx on xx.id=nc.id+1
where keys='name'
但是,代码依赖于关于键的错误假设...
答案 2 :(得分:0)
我认为原来的行式表设计因缺少另一个人的身份而存在缺陷。例如,SSN或任何唯一的人标识符键,以及名称,年龄和行ID。
答案 3 :(得分:0)
如果我猜对了,你想要一个关于名称和年龄的透视视图,因此需要不寻常的数据格式。您可以做的是关联数据,例如name:hulk
和age:22
,等等。所以你能做的是:
declare @t table (id int,keys varchar(10),val varchar(10))
insert into @t (id,keys,val)values (1,'name','hulk'),(1,'age','22'),
(2,'name','ironman'),(2,'age','35');
with CTE AS (
Select [name],CAST([age] AS INT)age from (
select id,keys,val from @t )t
PIVOT(MAX(val) for KEYS in ([name],[age]))P
GROUP BY [name],age)
Select (C.name),(C.AGE) from CTE C
LEFT JOIN CTE cc ON c.age = cc.age AND c.name = cc.name
创建关系后,您将获得所需的输出。我通过输入name:hulk
和age:22
的ID为1来创建关系,方法是输入的数据是针对相同的ID Id:1
,或者可以是您在应用中使用的任何对象这个数据。