2009-09-25 75 views
2

我有一個包含Student ID,Service和Provider的表。我想爲每個服務顯示DISTINCT提供程序,但只顯示NULL提供程序(如果沒有其他提供程序用於該服務和ID)。選擇distinct,non-null,除非null是該記錄組合的唯一值(tsql)

換句話說,如果學生有某個提供者和服務,我不想選擇提供者爲NULL的位置,除非該特定的Student和提供者沒有另一個非NULL提供者,在這種情況下,I是否要選擇NULL提供者行。我也不想爲非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 

因此,舉例來說,學生1具有非NULL和服務「SL」的NULL提供程序,所以我只想顯示非NULL提供程序Joe。學生2有四個「Sped」提供者:Mary(兩次),Jim和NULL,所以我只想顯示Mary(一次)和Jim。學生3有服務「SL」兩次,拉里和NULL,所以我只想顯示拉里。但是,學生3對於「OT」具有NULL,並且由於該學生/提供者組合沒有非NULL值,所以我想要顯示該行的NULL值。

本報告旨在向服務提供商展示他們在哪裏爲學生提供了一個提供者(一件好事),同時也表明了學生沒有任何提供者的服務(壞事)。我的用戶很容易混淆,所以我需要以這種方式呈現。感謝您的任何幫助!

+0

由KM給出的答案很優雅,我非常感謝詳細的解釋,但是......我爲美國一家州政府機構工作,而且我們仍然在SQL Server 2000上。ROW_NUMBER()無效SQL Server 2000,所以備選答案將不勝感激。 對於沒有注意到我們提前使用的軟件版本,我表示歉意,我沒有考慮它。 – Daniel

+0

查看最新編輯爲SQL Server 2000版本 –

回答

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 

OUTPUT:

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

(5 row(s) affected) 

編輯版OP後表示,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) 
+0

謝謝,謝謝!這正是我需要的。我收到一條關於「模棱兩可的列名」的消息,但最後一行是「ORDER BY y.ID,y.Service,y.provider」,它的效果很好。我非常感謝你的幫助和時間。 – Daniel

+0

+1感謝您的解決方案。後人注意事項:在分區聲明中,我必須切換「order by」子句才能使空值在分區開始時不顯示。 –