选择distinct,非null,除非null是该记录组合(tsql)的唯一值

选择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、服务和提供者的桌子。我想为每个服务显示不同的提供者,但只有在没有其他提供者用于该服务和ID时才显示空提供者

换句话说,如果一个学生有一个特定的提供者和服务,我不想选择提供者为NULL的位置,除非那个特定的学生和提供者没有另一个非NULL提供者,在这种情况下,我想选择NULL提供者行。我也不希望非空值重复

下面是一个示例表:

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”子句,以使空值永远不会出现在分区的开始处。