[转]SQL函数——将一对多关系转换成一对一关系

简介:
我们经常会遇到想要把一对多关系转换成为一对一关系,以方便显示。例如有如下关系:
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,如需转载请自行联系原作者

相关文章
|
3月前
|
SQL Oracle 关系型数据库
SQL优化-使用联合索引和函数索引
在一次例行巡检中,发现一条使用 `to_char` 函数将日期转换为字符串的 SQL 语句 CPU 利用率很高。为了优化该语句,首先分析了 where 条件中各列的选择性,并创建了不同类型的索引,包括普通索引、函数索引和虚拟列索引。通过对比不同索引的执行计划,最终确定了使用复合索引(包含函数表达式)能够显著降低查询成本,提高执行效率。
|
3月前
|
SQL 数据库 数据库管理
数据库SQL函数应用技巧与方法
在数据库管理中,SQL函数是处理和分析数据的强大工具
|
3月前
|
SQL 数据库 索引
SQL中COUNT函数结合条件使用的技巧与方法
在SQL查询中,COUNT函数是一个非常常用的聚合函数,用于计算表中满足特定条件的记录数
|
3月前
|
SQL 关系型数据库 MySQL
SQL日期函数
SQL日期函数
|
5月前
|
SQL 数据库
|
5月前
|
SQL 数据采集 数据处理
如何在 SQL Server 中使用 LEN 函数
【8月更文挑战第9天】
210 1
如何在 SQL Server 中使用 LEN 函数
|
4月前
|
SQL 关系型数据库 C语言
PostgreSQL SQL扩展 ---- C语言函数(三)
可以用C(或者与C兼容,比如C++)语言编写用户自定义函数(User-defined functions)。这些函数被编译到动态可加载目标文件(也称为共享库)中并被守护进程加载到服务中。“C语言函数”与“内部函数”的区别就在于动态加载这个特性,二者的实际编码约定本质上是相同的(因此,标准的内部函数库为用户自定义C语言函数提供了丰富的示例代码)
|
5月前
|
SQL 数据处理 数据库
SQL中的函数有哪些类型
【8月更文挑战第20天】SQL中的函数有哪些类型
59 1
|
5月前
|
SQL 监控 索引
如何在 SQL Server 中使用 `PATINDEX` 函数
【8月更文挑战第8天】
515 9
|
5月前
|
SQL 数据处理 数据库