我們經常會遇到想要把一對多關系轉換成為一對一關系,以友善顯示。例如有如下關系:
Class(ClassID,ClassName)和Student(SID,SName,ClassID),并且,這兩個關系存在以下測試資料:
Class:
001
國文
002
數學
Student:
031231301
張三
031231302
李四
那麼,這兩個關系表達的意思:選國文的有張三和李四;選數學的有李四。如果想做一個視圖(V_STU_CLA)來表達這種一對多關系(一門課程,被多個學生所選擇),可以使用一個簡單的左聯語句來完成:
SELECT C.ClassID, C.ClassName, S.SName FROM Class C
LEFT JOIN Student S ON C.ClassID=S.ClassID;
得到的結果如下:
ClassID
ClassName
SName
這樣雖然能夠清晰的表達選課關系,但是,某些情況下,它不如下面這種形式來得一目了然:
SNames
張三,李四
要達到這樣的目的,需要完成一個一對多關系到一對一關系的轉換。這樣的轉換,在資料庫中,可以借助函數來進行,因為函數中應用到了遊标,故對于Oracle和MSSQL稍有不同,附上兩個版本的函數SQL代碼:
MS-SQL版:
--根據課程ID,傳回選此課程的學生的名字,以逗号隔開
CREATE function dbo.f_getStuNamesByClassID (@ClassID int)
RETURNS nvarchar(512)
begin
declare @Result nvarchar(512);
declare @stuName nvarchar(256);
Set @Result='';
declare cur cursor for
(
SELECT S.SName FROM Class C
LEFT JOIN Student S ON C.ClassID=S.ClassID
WHERE C.ClassID=@ClassID
)
open cur;
fetch next from cur into @stuName;
while(@@fetch_status=0)
begin
set @Result=@Result+@stuName+',';
fetch next from cur into @stuName;
end;
--去除最後多餘的一個逗号
IF @Result <> ''
SET @Result=SUBSTRING(@Result, 1, LEN(@Result)-1);
ELSE
SET @Result=NULL;
return @Result;
end
ORACLE版:
create or replace function FUN_GET_STUNAMES_BY_CLASSID(P_CLASSID IN VARCHAR2) return varchar2 is
Result VARCHAR2(4000);
--通過遊标,查找并拼接此課程下的學生姓名
FOR CUR IN
(
SELECT S.SName FROM Class C
WHERE C.ClassID=@ClassID;
)
LOOP
Result := Result||CUR.SName||',';
END LOOP;
--去掉最後一個逗号
Result:=SUBSTR(Result,0,LENGTH(Result)-1);
return(Result);
end;
MS-SQL調用時,通過以下語句實作:
SELECT C.ClassID, C.ClassName, dbo.f_getStuNamesByClassID(C.ClassID)
FROM Class C;
ORACLE中調用方法類似。
本文轉自Jack Niu部落格園部落格,原文連結:http://www.cnblogs.com/skywind/archive/2008/04/09/1144676.html,如需轉載請自行聯系原作者