选择distinct,非null,除非null是该记录组合(tsql)的唯一值
我有一张带有学生ID、服务和提供者的桌子。我想为每个服务显示不同的提供者,但只有在没有其他提供者用于该服务和ID时才显示空提供者 换句话说,如果一个学生有一个特定的提供者和服务,我不想选择提供者为NULL的位置,除非那个特定的学生和提供者没有另一个非NULL提供者,在这种情况下,我想选择NULL提供者行。我也不希望非空值重复 下面是一个示例表:选择distinct,非null,除非null是该记录组合(tsql)的唯一值,tsql,sql-server-2000,Tsql,Sql Server 2000,我有一张带有学生ID、服务和提供者的桌子。我想为每个服务显示不同的提供者,但只有在没有其他提供者用于该服务和ID时才显示空提供者 换句话说,如果一个学生有一个特定的提供者和服务,我不想选择提供者为NULL的位置,除非那个特定的学生和提供者没有另一个非NULL提供者,在这种情况下,我想选择NULL提供者行。我也不希望非空值重复 下面是一个示例表: ID Service Provider 1 SL Joe 1 SL NULL 2 Sped Mary
ID Service Provider
1 SL Joe
1 SL NULL
2 Sped Mary
2 Sped Jim
2 Sped NULL
2 Sped Mary
3 SL Larry
3 OT NULL
3 SL NULL
我希望通过我的选择得到的结果是:
ID Service Provider
1 SL Joe
2 Sped Mary
2 Sped Jim
3 SL Larry
3 OT NULL
例如,Student 1的服务“SL”有一个非NULL和一个NULL提供程序,所以我只想显示非NULL提供程序Joe。学生2有四个“Sped”提供者:Mary(两次)、Jim和NULL,所以我只想显示Mary(一次)和Jim。学生3有两次服务“SL”,分别是Larry和NULL,所以我只想给Larry看。但是,Student 3的“OT”有一个空值,因为该Student/Provider组合没有非空值,所以我想显示该行的空值
本报告旨在向服务提供商展示他们在哪里为学生提供了服务提供商(一件好事),但也向学生展示了没有任何提供商的服务提供商(一件坏事)。我的用户很容易混淆,因此我需要以这种方式展示。谢谢你的帮助 试试这个(在OP说他们在SQL Server 2000上之前):
输出:
ID Service provider
----------- ------- --------
1 SL Joe
2 Sped Jim
2 Sped Mary
3 OT NULL
3 SL Larry
(5 row(s) affected)
ID Service provider
----------- ------- --------
1 SL Joe
2 Sped Jim
2 Sped Mary
3 OT NULL
3 SL Larry
Warning: Null value is eliminated by an aggregate or other SET operation.
(5 row(s) affected)
编辑SQL Server 2000之后的版本:
--ONLY WORKS ON SQl Server 2005 and up
DECLARE @YourTable table (ID int, Service varchar(5), provider varchar(5))
SET NOCOUNT ON
INSERT INTO @YourTable VALUES (1,'SL' ,'Joe')
INSERT INTO @YourTable VALUES (1,'SL' ,NULL)
INSERT INTO @YourTable VALUES (2,'Sped','Mary')
INSERT INTO @YourTable VALUES (2,'Sped','Jim')
INSERT INTO @YourTable VALUES (2,'Sped',NULL)
INSERT INTO @YourTable VALUES (2,'Sped','Mary')
INSERT INTO @YourTable VALUES (3,'SL' ,'Larry ')
INSERT INTO @YourTable VALUES (3,'OT' ,NULL)
INSERT INTO @YourTable VALUES (3,'SL' ,NULL)
SET NOCOUNT OFF
SELECT DISTINCT
ID,Service,provider
FROM (SELECT
ID,Service,provider,ROW_NUMBER() OVER(PARTITION BY ID,Service ORDER BY ID,Service,Provider desc) AS Rank
FROM @YourTable
) dt
WHERE dt.provider IS NOT NULL OR dt.Rank=1
ORDER BY ID,Service,provider
CREATE TABLE #YourTable (ID int, Service varchar(5), provider varchar(5))
SET NOCOUNT ON
INSERT INTO #YourTable VALUES (1,'SL' ,'Joe')
INSERT INTO #YourTable VALUES (1,'SL' ,NULL)
INSERT INTO #YourTable VALUES (2,'Sped','Mary')
INSERT INTO #YourTable VALUES (2,'Sped','Jim')
INSERT INTO #YourTable VALUES (2,'Sped',NULL)
INSERT INTO #YourTable VALUES (2,'Sped','Mary')
INSERT INTO #YourTable VALUES (3,'SL' ,'Larry ')
INSERT INTO #YourTable VALUES (3,'OT' ,NULL)
INSERT INTO #YourTable VALUES (3,'SL' ,NULL)
SET NOCOUNT OFF
SELECT
y.ID,y.Service,y.provider
FROM #YourTable y
INNER JOIN (SELECT
ID,Service,MAX(provider) AS MaxProvider
FROM #YourTable
GROUP BY ID,Service
HAVING MAX(provider) IS NOT NULL
) dt ON y.ID=dt.ID AND y.Service=dt.Service
WHERE provider IS NOT NULL
UNION
SELECT
ID,Service,MAX(provider) AS MaxProvider
FROM #YourTable
GROUP BY ID,Service
HAVING MAX(provider) IS NULL
ORDER BY ID,Service,provider
输出:
ID Service provider
----------- ------- --------
1 SL Joe
2 Sped Jim
2 Sped Mary
3 OT NULL
3 SL Larry
(5 row(s) affected)
ID Service provider
----------- ------- --------
1 SL Joe
2 Sped Jim
2 Sped Mary
3 OT NULL
3 SL Larry
Warning: Null value is eliminated by an aggregate or other SET operation.
(5 row(s) affected)
KM给出的答案很优雅,我非常感谢您的详细解释,但是……我在一家美国国家机构工作,我们仍然使用SQL Server 2000。ROW_NUMBER()在SQL Server 2000中无效,因此请提供其他答案。很抱歉没有提前注意到我们正在使用的软件版本,我没有考虑它。请参阅SQL Server 2000版本的最新编辑谢谢!这正是我需要的。我收到了一条关于“模棱两可的列名”的消息,但我刚刚写了最后一行“ORDER BY y.ID,y.Service,y.provider”,效果很好。我非常感谢您的帮助和时间。+1感谢您的解决方案。后人注意:在分区语句中,我必须切换“orderby”子句,以使空值永远不会出现在分区的开始处。