`

动态SQL

阅读更多

表有三列,stunamem,subject score.
表中的数据有:
张三 语文 0
李四 语文 4
王二 英文 90
张三 数学 333
要求查询结果如下
学生 语文 英文 数学
张三 0 0 333
李四 4 0 0
没有分数的默认为0


求查询SQL


等楼下.


使用 case when


SQL code

/*

标题:普通行列转换(version 2.0)

作者:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开)

时间:2008-03-09

地点:广东深圳

说明:普通行列转换(version 1.0)仅针对sql server 2000提供静态和动态写法,version 2.0增加sql server 2005的有关写法。



问题:假设有张学生成绩表(tb)如下:

姓名 课程 分数

张三 语文 74

张三 数学 83

张三 物理 93

李四 语文 74

李四 数学 84

李四 物理 94

想变成(得到如下结果):

姓名 语文 数学 物理

---- ---- ---- ----

李四 74 84 94

张三 74 83 93

-------------------

*/



create table tb(姓名 varchar(10) , 课程 varchar(10) , 分数 int)

insert into tb values('张三' , '语文' , 74)

insert into tb values('张三' , '数学' , 83)

insert into tb values('张三' , '物理' , 93)

insert into tb values('李四' , '语文' , 74)

insert into tb values('李四' , '数学' , 84)

insert into tb values('李四' , '物理' , 94)

go



--SQL SERVER 2000 静态SQL,指课程只有语文、数学、物理这三门课程。(以下同)

select 姓名 as 姓名 ,

max(case 课程 when '语文' then 分数 else 0 end) 语文,

max(case 课程 when '数学' then 分数 else 0 end) 数学,

max(case 课程 when '物理' then 分数 else 0 end) 物理

from tb

group by 姓名



--SQL SERVER 2000 动态SQL,指课程不止语文、数学、物理这三门课程。(以下同)

declare @sql varchar(8000)

set @sql = 'select 姓名 '

select @sql = @sql + ' , max(case 课程 when ''' + 课程 + ''' then 分数 else 0 end) [' + 课程 + ']'

from (select distinct 课程 from tb) as a

set @sql = @sql + ' from tb group by 姓名'

exec(@sql)



--SQL SERVER 2005 静态SQL。

select * from (select * from tb) a pivot (max(分数) for 课程 in (语文,数学,物理)) b



--SQL SERVER 2005 动态SQL。

declare @sql varchar(8000)

select @sql = isnull(@sql + '],[' , '') + 课程 from tb group by 课程

set @sql = '[' + @sql + ']'

exec ('select * from (select * from tb) a pivot (max(分数) for 课程 in (' + @sql + ')) b')



---------------------------------



/*

问题:在上述结果的基础上加平均分,总分,得到如下结果:

姓名 语文 数学 物理 平均分 总分

---- ---- ---- ---- ------ ----

李四 74 84 94 84.00 252

张三 74 83 93 83.33 250

*/



--SQL SERVER 2000 静态SQL。

select 姓名 姓名,

max(case 课程 when '语文' then 分数 else 0 end) 语文,

max(case 课程 when '数学' then 分数 else 0 end) 数学,

max(case 课程 when '物理' then 分数 else 0 end) 物理,

cast(avg(分数*1.0) as decimal(18,2)) 平均分,

sum(分数) 总分

from tb

group by 姓名



--SQL SERVER 2000 动态SQL。

declare @sql varchar(8000)

set @sql = 'select 姓名 '

select @sql = @sql + ' , max(case 课程 when ''' + 课程 + ''' then 分数 else 0 end) [' + 课程 + ']'

from (select distinct 课程 from tb) as a

set @sql = @sql + ' , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名'

exec(@sql)



--SQL SERVER 2005 静态SQL。

select m.* , n.平均分 , n.总分 from

(select * from (select * from tb) a pivot (max(分数) for 课程 in (语文,数学,物理)) b) m,

(select 姓名 , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名) n

where m.姓名 = n.姓名



--SQL SERVER 2005 动态SQL。

declare @sql varchar(8000)

select @sql = isnull(@sql + ',' , '') + 课程 from tb group by 课程

exec ('select m.* , n.平均分 , n.总分 from

(select * from (select * from tb) a pivot (max(分数) for 课程 in (' + @sql + ')) b) m ,

(select 姓名 , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名) n

where m.姓名 = n.姓名')



drop table tb



------------------

------------------



/*

问题:如果上述两表互相换一下:即表结构和数据为:

姓名 语文 数学 物理

张三 74  83  93

李四 74  84  94

想变成(得到如下结果):

姓名 课程 分数

---- ---- ----

李四 语文 74

李四 数学 84

李四 物理 94

张三 语文 74

张三 数学 83

张三 物理 93

--------------

*/



create table tb(姓名 varchar(10) , 语文 int , 数学 int , 物理 int)

insert into tb values('张三',74,83,93)

insert into tb values('李四',74,84,94)

go



--SQL SERVER 2000 静态SQL。

select * from

(

select 姓名 , 课程 = '语文' , 分数 = 语文 from tb

union all

select 姓名 , 课程 = '数学' , 分数 = 数学 from tb

union all

select 姓名 , 课程 = '物理' , 分数 = 物理 from tb

) t

order by 姓名 , case 课程 when '语文' then 1 when '数学' then 2 when '物理' then 3 end



--SQL SERVER 2000 动态SQL。

--调用系统表动态生态。

declare @sql varchar(8000)

select @sql = isnull(@sql + ' union all ' , '' ) + ' select 姓名 , [课程] = ' + quotename(Name , '''') + ' , [分数] = ' + quotename(Name) + ' from tb'

from syscolumns

where name! = N'姓名' and ID = object_id('tb') --表名tb,不包含列名为姓名的其它列

order by colid asc

exec(@sql + ' order by 姓名 ')



--SQL SERVER 2005 动态SQL。

select 姓名 , 课程 , 分数 from tb unpivot (分数 for 课程 in([语文] , [数学] , [物理])) t



--SQL SERVER 2005 动态SQL,同SQL SERVER 2000 动态SQL。



--------------------

/*

问题:在上述的结果上加个平均分,总分,得到如下结果:

姓名 课程 分数

---- ------ ------

李四 语文 74.00

李四 数学 84.00

李四 物理 94.00

李四 平均分 84.00

李四 总分 252.00

张三 语文 74.00

张三 数学 83.00

张三 物理 93.00

张三 平均分 83.33

张三 总分 250.00

------------------

*/



select * from

(

select 姓名 as 姓名 , 课程 = '语文' , 分数 = 语文 from tb

union all

select 姓名 as 姓名 , 课程 = '数学' , 分数 = 数学 from tb

union all

select 姓名 as 姓名 , 课程 = '物理' , 分数 = 物理 from tb

union all

select 姓名 as 姓名 , 课程 = '平均分' , 分数 = cast((语文 + 数学 + 物理)*1.0/3 as decimal(18,2)) from tb

union all

select 姓名 as 姓名 , 课程 = '总分' , 分数 = 语文 + 数学 + 物理 from tb

) t

order by 姓名 , case 课程 when '语文' then 1 when '数学' then 2 when '物理' then 3 when '平均分' then 4 when '总分' then 5 end



drop table tb



SQL code

create table #test (stunamem varchar(10),subject varchar(10),score int)

insert #test select '张三', '语文', 0

insert #test select '李四', '语文', 4

insert #test select '王二', '英文', 90

insert #test select '张三', '数学', 333







select stunamem,max(case when subject='语文' then score else 0 end)

,max(case when subject='英文' then score else 0 end)

,max(case when subject='数学' then score else 0 end)

from #test

group by stunamem

stunamem

---------- ----------- ----------- -----------

李四 4 0 0

王二 0 90 0

张三 0 0 333



(3 行受影响)



如果是2005的话,可以使用pivot函数。
SQL code



,[1996],[1997],[1998]

FROM dbo.Orders

PIVOT (

SUM(Quantity)

FOR [Year] IN ([1996],[1997],[1998])

)x

--结果:

CustomerID 1996 1997 1998

---------- ----------- ----------- -----------

ANTON 24 295 40

BONAP 181 486 313

BOTTM 81 454 421






更多请参考: SQL server 2005 PIVOT运算符的使用


[code=SQL]
USE   tempdb
GO
SELECT   YEAR(OrderDate)   AS   [Year]
              ,CustomerID  
              ,od.Quantity
INTO   dbo.Orders              
FROM   NorthWind..Orders   AS   o
        JOIN   NorthWind..[Order   Details]   AS   od
                ON   o.OrderID   =   od.OrderID
WHERE   o.CustomerID   IN   ( 'BONAP ', 'BOTTM ', 'ANTON ')

SELECT   CustomerID
,[1996],[1997],[1998]
FROM   dbo.Orders
PIVOT   (
      SUM(Quantity)
      FOR   [Year]   IN   ([1996],[1997],[1998])
      )x
   
--结果:    
CustomerID   1996                 1997                 1998
----------   -----------   -----------   -----------
ANTON             24                     295                   40
BONAP             181                   486                   313
BOTTM             81                     454                   421


[/code]

分享到:
评论

相关推荐

    hibernate实现动态SQL查询

    本篇文章主要探讨如何利用Hibernate实现动态SQL查询,结合XML配置和FREEMARKER模板引擎来生成执行的SQL语句。 一、Hibernate简介 Hibernate作为一款强大的持久层框架,它简化了Java应用程序与数据库之间的交互。...

    kettel循环执行动态sql

    标题中的“Kettle循环执行动态SQL”指的是使用Pentaho Data Integration(Kettle)工具来设计数据集成工作流,其中包含动态生成并执行SQL语句的步骤。在数据处理和ETL(Extract, Transform, Load)过程中,动态SQL是...

    静态、动态sql及各种游标

    静态、动态SQL及各种游标 静态SQL和动态SQL是两种不同的SQL语句执行方式,分别应用于不同的场景中。静态SQL是指在PL/SQL中直接运行的SQL语句,没有什么特别之处。动态SQL则是指利用EXECUTE IMMEDIATE语句执行的SQL...

    Gbase8s动态sql的介绍

    Gbase8s 动态 SQL 介绍 Gbase8s 动态 SQL 介绍 在 Gbase8s 中,动态 SQL 是一种特殊的 SQL 语句形式,它可以在执行时动态改变 SQL 语句的内容,不需要预先知道每个 SQL 语句的确切内容。与静态 SQL 不同,静态 SQL...

    动态SQL 并且把返回的值赋给变量

    ### 动态SQL 并且把返回的值赋给变量 在SQL Server中,动态SQL是一种强大而灵活的工具,允许开发人员根据运行时条件构建并执行SQL查询。本文将详细介绍如何利用`sp_executesql`来执行动态SQL,并重点讨论如何将执行...

    mybatis 动态sql及参数传递

    在实际开发过程中,我们往往需要编写复杂的SQL语句,拼接稍有不注意就会导致错误,Mybatis给开发者提供了动态SQL,大大降低了拼接SQL导致的错误。 动态标签 if标签 if标签通常用那个胡where语句,update语句,insert...

    本地动态SQL的开发

    ### 本地动态SQL的开发 #### 一、动态SQL的概念 动态SQL是在程序运行时构建并执行的SQL语句,其内容无法在编译时完全确定。与静态SQL(如常见的`UPDATE`语句)不同,动态SQL允许开发者在运行时根据实际情况构建...

    SQLServer动态SQL语句的用法

    SQL Server 动态 SQL 语句的用法 SQL Server 中的动态 SQL 语句是一种灵活的查询方式,它可以根据不同的情况生成不同的 SQL 语句。动态 SQL 语句可以用来实现复杂的业务逻辑,提高查询效率和灵活性。 普通 SQL ...

    mybatis之动态SQL

    动态 SQL 是 MyBatis 的一大特色,它允许我们在运行时根据条件构建 SQL 语句,极大地提高了代码的可维护性和灵活性。 动态 SQL 在 MyBatis 中主要通过 XML 映射文件或者注解来实现。在 XML 映射文件中,我们可以...

    DB2游标及动态SQL

    ### DB2游标及动态SQL详解 #### 一、DB2游标概念与使用 **1.1 游标简介** 在DB2中,游标是一种用于遍历查询结果集的强大工具。它允许用户一行一行地处理数据,这对于需要逐行处理数据的应用场景非常有用。游标通常...

    ibatis动态SQL标签用法

    iBatis动态SQL标签用法 iBatis是Java持久层框架,提供了动态SQL标签来实现动态查询。动态SQL标签可以根据不同的条件生成不同的SQL语句,从而提高查询效率和灵活性。 动态SQL片段 iBatis提供了动态SQL片段的功能,...

    动态SQL与绑定变量

    动态SQL与绑定变量是数据库编程中的重要概念,尤其在Oracle数据库中被广泛应用。动态SQL允许在运行时构建和执行SQL语句,而绑定变量则是在动态SQL中用于替代具体值的占位符,使得SQL语句更为灵活和高效。 ### 1. ...

    一款IDEA插件,可以实现生成Mysql的动态SQL,适合新手使用mybatis来写项目,加快项目落地周期.zip

    mybatis动态sql 1.什么是动态SQL? Mabits是一个Java持久化框架,它提供了动态SQL的功能。动态SQL是一种根据不同条件动态生成SQL语句的技术。在Mabits中,动态SQL通常是通过使用一组特殊的标签和代码块来实现的,...

    sql语句、动态SQL语句基本语法

    SQL(Structured Query Language)是用于管理和操作...综上所述,掌握SQL语句和动态SQL的基本语法对于任何IT从业者来说都至关重要,无论是数据库管理员还是开发者,都需要熟练运用这些技能来高效地操作和管理数据库。

    学习SQL应知道的动态SQL语句基本语法 mssql

    在SQL世界中,动态SQL(Dynamic SQL)是一种强大的技术,特别是在复杂的数据库操作和程序设计中。在Microsoft SQL Server(MSSQL)环境下,掌握动态SQL的基本语法是提升SQL编程能力的关键。下面,我们将深入探讨动态...

    《kettle中实现动态SQL查询》博客文章示例代码

    本文将深入探讨如何在Kettle中实现动态SQL查询,这对于处理复杂的数据库操作和数据迁移至关重要。我们将讨论问号占位符和命名参数这两种方法,并分析它们的区别。 首先,让我们理解什么是动态SQL查询。在传统的SQL...

    SpringBoot+JPA+Freemarker 生成动态SQL

    本篇将详细讲解如何利用这些技术来生成动态SQL。 首先,SpringBoot是Spring框架的一个轻量级版本,它简化了配置,提供了一种快速开发全新Spring应用的方式。SpringBoot集成了大量的常用库,如数据访问、安全、缓存...

    Oracle中动态SQL详解

    ### Oracle中动态SQL详解 #### 一、动态SQL概述与特点 在Oracle数据库中,动态SQL是一种非常重要的技术,尤其对于开发人员来说更是必不可少的一部分。动态SQL是指在运行时构建并执行的SQL语句,与静态SQL(在编译...

    hibernate增删改查和动态sql

    “hibernate增删改查和动态sql”这个标题涵盖了两个主要的Hibernate使用场景。首先,"增删改查"(CRUD操作)是任何数据库操作的基础,包括创建(Create)、读取(Read)、更新(Update)和删除(Delete)。在...

Global site tag (gtag.js) - Google Analytics