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

时间:2009-09-25 18:03:51

标签: tsql sql-server-2000

我有一张包含学生证,服务和提供者的表。我想为每个服务显示DISTINCT提供程序,但如果没有该服务和ID的其他提供程序,则只显示NULL提供程序。

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

这是一个示例表:

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具有非NULL和服务“SL”的NULL提供程序,所以我只想显示非NULL提供程序Joe。学生2有四个“速度”提供者:Mary(两次),Jim和NULL,所以我只想展示Mary(曾经)和Jim。学生3有服务“SL”两次,拉里和NULL,所以我只想展示拉里。但是,Student 3的“OT”为NULL,并且由于该Student / Provider组合没有非NULL值,我想显示该行的NULL值。

本报告旨在向服务提供商展示他们为学生提供的服务提供商(一件好事),以及学生在没有任何提供者的情况下提供服务(一件坏事)。我的用户很容易混淆,所以我需要以这种方式呈现它。谢谢你的帮助!

1 个答案:

答案 0 :(得分:3)

试试这个(在OP说他们在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

输出:

ID          Service provider
----------- ------- --------
1           SL      Joe
2           Sped    Jim
2           Sped    Mary
3           OT      NULL
3           SL      Larry

(5 row(s) affected)
OP之后的

EDIT 版本说SQL Server 2000:

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
Warning: Null value is eliminated by an aggregate or other SET operation.

(5 row(s) affected)