SQL Server中的两行合二为一

时间:2017-06-07 13:43:35

标签: sql sql-server select

答案太近了,谢谢 但 问题是如果要输入太多记录

           |    id   |    name   |    age    |   Tel
------------------------------------------
      1    |    1   |   Frank   |    40     |   null
      2    |    1   |   null    |    50     |   7834xx
      3    |    1   |   Alex    |    null   |   null
      4    |    1   |   null    |    20     |   null
      5    |    2   |   James   |    null   |   4121xx

查询返回最大值 像:

           |    id   |   name    |    age    |   Tel
------------------------------------------
      1    |    1    |   Frank   |    50     |  7834xx

我需要像这样选择查询:

           |    id   |   name    |    age    |   Tel
------------------------------------------
      1    |    1    |   Alex    |    20     |  7834xx

我该怎么办? PLZ?

3 个答案:

答案 0 :(得分:1)

一种简单的方法是获得以下最大值:

 Select Id, Max(name) as [Name], Max(age) as Age, Max(Tel) as Tel
 from yourtable
 Group by Id

答案 1 :(得分:1)

这是一种结合3列的最后一个非空值的迂回方式:

-- Using a table variable for test data
declare @Test table (tableId int identity(1,1), id int, name varchar(100), age int, tel varchar(30));
insert into @Test (id, name, age, tel) values
(1,'Frank',40,null),
(1,null,50,'7834xx'),
(1,'Alex',null,null),
(1,null,20,null),
(2,'James',null,'4121xx');

select n.id, n.name, a.age, t.tel
from (
    select top(1) with ties id, name 
    from @Test 
    where name is not null
    order by row_number() over (partition by id order by tableId desc)
) n
inner join (
    select top(1) with ties id, age 
    from @Test 
    where age is not null
    order by row_number() over (partition by id order by tableId desc)
) a on (n.id = a.id)
inner join (
    select top(1) with ties id, tel 
    from @Test 
    where tel is not null
    order by row_number() over (partition by id order by tableId desc)
) t on (n.id = t.id);

或重新使用CTE

;with CTE AS (
    select * ,
    row_number() over (partition by id, iif(name is not null,1,0) order by tableId desc) as rn_name,
    row_number() over (partition by id, iif(age is not null,1,0) order by tableId desc) as rn_age,
    row_number() over (partition by id, iif(tel is not null,1,0) order by tableId desc) as rn_tel
    from @Test
 )
select n.id, n.name, a.age, t.tel
from CTE n
join CTE a on (a.id = n.id and a.age is not null and a.rn_age = 1)
join CTE t on (t.id = n.id and t.tel is not null and t.rn_tel = 1)
where (n.name is not null and n.rn_name = 1);

结果:

╔════╦══════╦═════╦════════╗
║ id ║ name ║ age ║  tel   ║
╠════╬══════╬═════╬════════╣
║  1 ║ Alex ║  20 ║ 7834xx ║
╚════╩══════╩═════╩════════╝

一年多以后看了这个答案 您也可以使用窗口函数first_value。
不使用任何连接。

select Id, name, age, tel
from
(
    select Id
    , row_number() over (partition by id order by tableId desc) as rn
    , first_value(name) over (partition by id order by iif(name is null,1,0), tableId desc) as name
    , first_value(age) over (partition by id order by iif(age is null,1,0), tableId desc) as age
    , first_value(tel) over (partition by id order by iif(tel is null,1,0), tableId desc) as tel
    from @Test
) q
where rn = 1
and name is not null and age is not null and tel is not null;

答案 2 :(得分:0)

感谢您的回答和帮助。 我找到了这个问题:

选择TOP 10     (SELECT top(1)name FROM test1,其中id = 1,name不是autoID desc的null order)作为名称     ,(选择top(1)age FROM test1,其中id = 1,age不是null命令,autoID desc)作为Age ,(选择top(1)Tel FROM test1,其中id = 1,Tel不是autoID desc的null顺序)作为Telephon     来自[dbo]。[test1]     按ID分组

它的工作!!! 但我还有另一种简单方法,也许就是这样:

选择Id,NotNull(name)作为[Name],NotNull(age)作为Age,NotNull(Tel)作为Tel  来自Idrtable Group by Id

???