Select 所有 null 但只有一个不为 null

Select all nulls but only one not null

我希望你能在这方面帮助我: 我有一个关于这些数据的故事

CREATE TABLE dbo.T
(
    SG char(3) NOT NULL,
    SEQNUM int NOT NULL,
    CO varchar(3) NOT NULL,
    FS varchar(12),
    RS varchar(12)
);
INSERT INTO dbo.T(SG,SEQNUM,CO,FS,RS)
VALUES
('054',0,'010','P1',NULL),
('054',1,'010','P2',NULL),
('054',10,'020','P3',NULL),
('054',11,'030','P4',NULL),
('054',12,'030','A1','A1'),
('054',13,'030','P5',NULL),
('054',14,'030','P6',NULL),
('154',10,'150','P7',NULL),
('154',14,'160','A2','A2'),
('154',15,'160','P8',NULL)

我需要实现的就是这个输出

SG  SEQNUM  CO  FS      RS
054 0       010 'P1'    NULL
054 1       010 'P2'    NULL
054 10      020 'P3'    NULL
054 12      030 'A1'    'A1'
154 10      150 'P7'    NULL
154 14      160 'A2'    'A2'

所以基本上这背后的逻辑是每当 FS = RS 时只保留此条目并用相同的 SG 和 CO 排序所有其他条目。在其他情况下保留数据。 对不起,我的英语不好。 我希望你明白我的意思:)

非常感谢!

您可以为此使用 NOT EXISTS

select *
from dbo.T t
where not exists
( 
  select 1
  from dbo.T d
  where d.SG = t.SG and d.CO = t.CO
    and d.FS = d.RS
    and (t.FS IS NULL OR t.RS IS NULL OR t.FS <> t.RS)
);

这也可以通过过滤不匹配项的左自连接来完成。

select t.*
from dbo.T t
left join dbo.T d
  on d.SG = t.SG and d.CO = t.CO
 and d.FS = d.RS
 and (t.FS IS NULL OR t.RS IS NULL OR t.FS <> t.RS)
where d.SG is null

db<>fiddle here

的测试

请注意,该测试在 SG 和 CO 上放置了一个组合索引