博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[转]SQL函数——将一对多关系转换成一对一关系
阅读量:6223 次
发布时间:2019-06-21

本文共 1867 字,大约阅读时间需要 6 分钟。

我们经常会遇到想要把一对多关系转换成为一对一关系,以方便显示。例如有如下关系:
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;

得到的结果如下:

ClassID

ClassName

SName

001

语文

张三

001

语文

李四

002

数学

张三

这样虽然能够清晰的表达选课关系,但是,某些情况下,它不如下面这种形式来得一目了然:

ClassID

ClassName

SNames

001

语文

张三,李四

002

数学

张三

要达到这样的目的,需要完成一个一对多关系到一对一关系的转换。这样的转换,在数据库中,可以借助函数来进行,因为函数中应用到了游标,故对于OracleMSSQL稍有不同,附上两个版本的函数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(@Result1LEN(@Result)-1
);
    
ELSE
        
SET @Result=NULL
;
    
return @Result
;
end

ORACLE版:

create or replace function FUN_GET_STUNAMES_BY_CLASSID(P_CLASSID IN VARCHAR2return 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
;

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,如需转载请自行联系原作者

你可能感兴趣的文章
Openstack的镜像属性
查看>>
【分享】用Canvas实现画板功能
查看>>
C++走向远洋——46(教师兼干部类、多重继承、派生)
查看>>
spring IOC源码分析(1)
查看>>
「深入理解计算系统」从Hello World开始
查看>>
手写Json转换
查看>>
Xception
查看>>
MySQL——约束(constraint)详解---转载
查看>>
模板函数
查看>>
phpcms v9实现wap单页教程
查看>>
浅析Java中的内存机制
查看>>
君子性非异也,善假于物也
查看>>
centos命令行安装mysql随机密码查看方法(遇到问题及其解决办法)
查看>>
调用WCF REST服务时,使用JSON
查看>>
B/S和C/S的区别
查看>>
PHP array_multisort—对多个数组或多维数组进行排序
查看>>
关于视频的点滴体会
查看>>
SSH: Transferred 0 file(s) 解决
查看>>
3297: [USACO2011 Open]forgot
查看>>
『Island 基环树直径』
查看>>