如何删除两列中的空值以仅显示数据

时间:2015-06-13 03:05:07

标签: sql sql-server

我要求将行值转换为列,但我试图删除空行并仅显示数据

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

4 个答案:

答案 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:hulkage: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:hulkage:22的ID为1来创建关系,方法是输入的数据是针对相同的ID Id:1,或者可以是您在应用中使用的任何对象这个数据。