天天看點

[轉]SQL函數——将一對多關系轉換成一對一關系

我們經常會遇到想要把一對多關系轉換成為一對一關系,以友善顯示。例如有如下關系:

Class(ClassID,ClassName)和Student(SID,SName,ClassID),并且,這兩個關系存在以下測試資料:

Class:

001

國文

002

數學

Student:

031231301

張三

031231302

李四

那麼,這兩個關系表達的意思:選國文的有張三和李四;選數學的有李四。如果想做一個視圖(V_STU_CLA)來表達這種一對多關系(一門課程,被多個學生所選擇),可以使用一個簡單的左聯語句來完成:

[轉]SQL函數——将一對多關系轉換成一對一關系

SELECT C.ClassID, C.ClassName, S.SName FROM Class C

[轉]SQL函數——将一對多關系轉換成一對一關系

LEFT JOIN Student S ON C.ClassID=S.ClassID;

[轉]SQL函數——将一對多關系轉換成一對一關系

得到的結果如下:

ClassID

ClassName

SName

這樣雖然能夠清晰的表達選課關系,但是,某些情況下,它不如下面這種形式來得一目了然:

SNames

張三,李四

要達到這樣的目的,需要完成一個一對多關系到一對一關系的轉換。這樣的轉換,在資料庫中,可以借助函數來進行,因為函數中應用到了遊标,故對于Oracle和MSSQL稍有不同,附上兩個版本的函數SQL代碼:

MS-SQL版:

[轉]SQL函數——将一對多關系轉換成一對一關系

--根據課程ID,傳回選此課程的學生的名字,以逗号隔開

[轉]SQL函數——将一對多關系轉換成一對一關系

CREATE function dbo.f_getStuNamesByClassID (@ClassID int)

[轉]SQL函數——将一對多關系轉換成一對一關系

RETURNS nvarchar(512)

[轉]SQL函數——将一對多關系轉換成一對一關系

begin

[轉]SQL函數——将一對多關系轉換成一對一關系

    declare @Result nvarchar(512);

[轉]SQL函數——将一對多關系轉換成一對一關系

    declare @stuName nvarchar(256);

[轉]SQL函數——将一對多關系轉換成一對一關系

    Set @Result='';

[轉]SQL函數——将一對多關系轉換成一對一關系
[轉]SQL函數——将一對多關系轉換成一對一關系

    declare cur cursor for

[轉]SQL函數——将一對多關系轉換成一對一關系

    (

[轉]SQL函數——将一對多關系轉換成一對一關系

        SELECT S.SName FROM Class C

[轉]SQL函數——将一對多關系轉換成一對一關系

        LEFT JOIN Student S ON C.ClassID=S.ClassID

[轉]SQL函數——将一對多關系轉換成一對一關系

        WHERE C.ClassID=@ClassID

[轉]SQL函數——将一對多關系轉換成一對一關系

    )

[轉]SQL函數——将一對多關系轉換成一對一關系

    open cur;

[轉]SQL函數——将一對多關系轉換成一對一關系

    fetch next from cur into @stuName;

[轉]SQL函數——将一對多關系轉換成一對一關系

    while(@@fetch_status=0)

[轉]SQL函數——将一對多關系轉換成一對一關系

    begin

[轉]SQL函數——将一對多關系轉換成一對一關系

        set @Result=@Result+@stuName+',';

[轉]SQL函數——将一對多關系轉換成一對一關系

        fetch next from cur into @stuName;

[轉]SQL函數——将一對多關系轉換成一對一關系

    end;

[轉]SQL函數——将一對多關系轉換成一對一關系

--去除最後多餘的一個逗号

[轉]SQL函數——将一對多關系轉換成一對一關系

    IF @Result <> '' 

[轉]SQL函數——将一對多關系轉換成一對一關系

        SET @Result=SUBSTRING(@Result, 1, LEN(@Result)-1);

[轉]SQL函數——将一對多關系轉換成一對一關系

    ELSE

[轉]SQL函數——将一對多關系轉換成一對一關系

        SET @Result=NULL;

[轉]SQL函數——将一對多關系轉換成一對一關系

    return @Result;

[轉]SQL函數——将一對多關系轉換成一對一關系

end

ORACLE版:

[轉]SQL函數——将一對多關系轉換成一對一關系

create or replace function FUN_GET_STUNAMES_BY_CLASSID(P_CLASSID IN VARCHAR2) return varchar2 is

[轉]SQL函數——将一對多關系轉換成一對一關系

  Result VARCHAR2(4000);

[轉]SQL函數——将一對多關系轉換成一對一關系
[轉]SQL函數——将一對多關系轉換成一對一關系

  --通過遊标,查找并拼接此課程下的學生姓名

[轉]SQL函數——将一對多關系轉換成一對一關系

  FOR CUR IN 

[轉]SQL函數——将一對多關系轉換成一對一關系

  (

[轉]SQL函數——将一對多關系轉換成一對一關系

          SELECT S.SName FROM Class C

[轉]SQL函數——将一對多關系轉換成一對一關系
[轉]SQL函數——将一對多關系轉換成一對一關系

        WHERE C.ClassID=@ClassID;

[轉]SQL函數——将一對多關系轉換成一對一關系

  ) 

[轉]SQL函數——将一對多關系轉換成一對一關系

  LOOP

[轉]SQL函數——将一對多關系轉換成一對一關系

      Result := Result||CUR.SName||',';

[轉]SQL函數——将一對多關系轉換成一對一關系

  END LOOP;

[轉]SQL函數——将一對多關系轉換成一對一關系

  --去掉最後一個逗号

[轉]SQL函數——将一對多關系轉換成一對一關系

  Result:=SUBSTR(Result,0,LENGTH(Result)-1);

[轉]SQL函數——将一對多關系轉換成一對一關系

  return(Result);

[轉]SQL函數——将一對多關系轉換成一對一關系

end;

[轉]SQL函數——将一對多關系轉換成一對一關系

MS-SQL調用時,通過以下語句實作:

[轉]SQL函數——将一對多關系轉換成一對一關系

SELECT C.ClassID, C.ClassName, dbo.f_getStuNamesByClassID(C.ClassID) 

[轉]SQL函數——将一對多關系轉換成一對一關系

FROM Class C;

[轉]SQL函數——将一對多關系轉換成一對一關系

ORACLE中調用方法類似。

本文轉自Jack Niu部落格園部落格,原文連結:http://www.cnblogs.com/skywind/archive/2008/04/09/1144676.html,如需轉載請自行聯系原作者