【Evil 域】SQL函式——將一對多關係轉換成一對一關係
我們經常會遇到想要把一對多關係轉換成為一對一關係,以方便顯示。例如有如下關係:
Class(ClassID,ClassName)和Student(SID,SName,ClassID),並且,這兩個關係存在以下測試資料:
Class(ClassID,ClassName)和Student(SID,SName,ClassID),並且,這兩個關係存在以下測試資料:
Class:
001 |
語文 |
002 |
數學 |
Student:
031231301 |
張三 |
001 |
031231301 |
張三 |
002 |
031231302 |
李四 |
001 |
那麼,這兩個關係表達的意思:選語文的有張三和李四;選數學的有李四。如果想做一個檢視(V_STU_CLA)來表達這種一對多關係(一門課程,被多個學生所選擇),可以使用一個簡單的左聯語句來完成:
SELECT C.ClassID, C.ClassName, S.SName FROM Class C
LEFT JOIN Student S ON C.ClassID=S.ClassID;
LEFT JOIN Student S ON C.ClassID=S.ClassID;
得到的結果如下:
ClassID |
ClassName |
SName |
001 |
語文 |
張三 |
001 |
語文 |
李四 |
002 |
數學 |
張三 |
這樣雖然能夠清晰的表達選課關係,但是,某些情況下,它不如下面這種形式來得一目瞭然:
ClassID |
ClassName |
SNames |
001 |
語文 |
張三,李四 |
002 |
數學 |
張三 |
要達到這樣的目的,需要完成一個一對多關係到一對一關係的轉換。這樣的轉換,在資料庫中,可以藉助函式來進行,因為函式中應用到了遊標,故對於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
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);
begin
--通過遊標,查詢並拼接此課程下的學生姓名
FOR CUR IN
(
SELECT S.SName FROM Class C
LEFT JOIN Student S ON C.ClassID=S.ClassID
WHERE C.ClassID=@ClassID;
)
LOOP
Result := Result||CUR.SName||',';
END LOOP;
--去掉最後一個逗號
Result:=SUBSTR(Result,0,LENGTH(Result)-1);
return(Result);
end;
Result VARCHAR2(4000);
begin
--通過遊標,查詢並拼接此課程下的學生姓名
FOR CUR IN
(
SELECT S.SName FROM Class C
LEFT JOIN Student S ON C.ClassID=S.ClassID
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;
FROM Class C;
ORACLE中呼叫方法類似。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-374432/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- JPA(3) 表關聯關係(多對一、一對多、多對多、一對一)
- gorm 關係一對一,一對多,多對多查詢GoORM
- MyBatis加強(1)~myBatis物件關係對映(多對一關係、一對多關係)、延遲/懶載入MyBatis物件
- Spring Data JPA 之 一對一,一對多,多對多 關係對映Spring
- hibernate(三) 一對多對映關係
- Spring Boot 入門系列(二十八) JPA 的實體對映關係,一對一,一對多,多對多關係對映!Spring Boot
- Hibernate對映檔案一對多關係薦
- 多對一(主鍵)關係,create問題
- JPA中對映關係詳細說明(一對多,多對一,一對一、多對多)、@JoinColumn、mappedBy說明APP
- hibernate 關係對映之 主鍵關聯一對一
- 我的一個主表和一個從表是一對多關係,但是從表又與其他表有一對多等關係,
- hibernate(五) hibernate一對一關係對映詳解
- Hibernate中有一對多關係,如何插入資料呢
- 多對多關係<EntityFramework6.0>Framework
- EF Code First中的主外來鍵約定和一對一、一對多關係的實現
- 資料庫表中一對多關係怎麼設計?資料庫
- orm2 中文文件 4.3 extendsTo(一對一關係)ORM
- MyBatis表關聯 一對多 多對一 多對多MyBatis
- Laravel 之多對多的關係模型Laravel模型
- hibernate(四) 雙向多對多對映關係
- 7.Hibernate一對多關係建立與錯誤解決
- HIBERNATE裡面怎麼繼承一對多的關係呢繼承
- MySQL(12)---紀錄一次left join一對多關係而引起的BUGMySql
- Laravel 中的多對多關係詳解Laravel
- 6.Hibernate多對多關係建立
- 域名和ip是多對多的關係
- mORMot2 定義多對多關係ORM
- Laravel 遠端一對多關係,中間表模型和關聯模型不能是同一個模型Laravel模型
- 由一個博問學到的SQL查詢方法 (一道多對多關係查詢的面試題)SQL面試題
- NULL和唯一約束UNIQUE的對應關係Null
- mybatis關聯關係對映MyBatis
- spring data jpa關聯查詢(一對一、一對多、多對多)Spring
- 關於Hibernate多層1對多關係查詢
- 在 CSDN 上面看到的一篇關於 Laravel 關聯表模型和多對多關係的文章Laravel模型
- hibernate中多對多關係的維護
- 3分鐘短文:說說Laravel模型關聯關係最單純的“一對一”Laravel模型
- 模型關聯一對多模型
- Django一對多關係模型Add a related_name argument to the definit的錯誤Django模型