问题是如果要输入太多记录
| 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
我的查询:
select id, max(name) as name, max(age) as age, max(tel) as tel
from Table group by id;
结果=返回最大值像:
| id | name | age | Tel
------------------------------------------
1 | 1 | Frank | 50 | 7834xx
但我需要像这样的Select Query: 例如:(也许): select id,lastRowsNotNull(name)as name,lastRowsNotNull(age)as age,lastRowsNotNull(tel)as table from table group by id;
| id | name | age | Tel
------------------------------------------
1 | 1 | Alex | 20 | 7834xx
我该怎么办?恳求?
答案 0 :(得分:2)
drop table if exists dbo.TableC;
create table dbo.TableC (
Ident int primary key
, Id int
, name varchar(100)
, age int
, Tel varchar(100)
);
insert into dbo.TableC (Ident, Id, name, age, Tel)
values (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');
select
*
from (
select
MIN(t.Ident) as Ident
, t.id
from dbo.TableC t
group by t.Id
) t
outer apply (
select
top (1)
tn.name
from dbo.TableC tn
where tn.name is not null
and tn.Id = t.Id
order by tn.Ident desc
) tname
outer apply (
select
top (1)
ta.age
from dbo.TableC ta
where ta.age is not null
and ta.Id = t.Id
order by ta.Ident desc
) tage
outer apply (
select
top (1)
tt.tel
from dbo.TableC tt
where tt.Tel is not null
and tt.Id = t.Id
order by tt.Ident desc
) ttel
答案 1 :(得分:1)
我尝试通过引入Cross Apply并选择顶部列值来简化逻辑 Demo
主要逻辑
SELECT id, name, age, Tel FROM
(SELECT MIN(rn) AS rn, id
FROM
#RecordsTable
GROUP BY id
) A
CROSS APPLY(
SELECT
(SELECT TOP 1 name FROM #RecordsTable WHERE name IS NOT NULL AND id = A.id Order by rn DESC) name,
(SELECT TOP 1 age FROM #RecordsTable WHERE age IS NOT NULL AND id = A.id Order by rn DESC) age,
(SELECT TOP 1 Tel FROM #RecordsTable WHERE Tel IS NOT NULL AND id = A.id Order by rn DESC) Tel
) B;
完整查询
IF OBJECT_ID('tempdb..#RecordsTable') IS NULL
BEGIN
CREATE TABLE tempdb..#RecordsTable(rn INT IDENTITY(1, 1) NOT NULL, id INT, name VARCHAR(MAX), age INT, Tel VARCHAR(MAX));
END
;WITH RecordsTable AS(
SELECT 1 AS id, 'Frank' AS name, 40 AS age, NULL AS Tel UNION ALL
SELECT 1 , NULL, 50, '7834xx' UNION ALL
SELECT 1, 'Alex', null, null UNION ALL
SELECT 1, null, 20, null UNION ALl
SELECT 2, 'James', null, '4121xxx'
)
INSERT INTO #RecordsTable
SELECT id, name, age, Tel FROM RecordsTable;
SELECT id, name, age, Tel FROM
(SELECT MIN(rn) AS rn, id
FROM
#RecordsTable
GROUP BY id
) A
CROSS APPLY(
SELECT
(SELECT TOP 1 name FROM #RecordsTable WHERE name IS NOT NULL AND id = A.id Order by rn DESC) name,
(SELECT TOP 1 age FROM #RecordsTable WHERE age IS NOT NULL AND id = A.id Order by rn DESC) age,
(SELECT TOP 1 Tel FROM #RecordsTable WHERE Tel IS NOT NULL AND id = A.id Order by rn DESC) Tel
) B;
DROP TABLE #RecordsTable
输出
1 Alex 20 7834xx
2 James NULL 4121xxx