博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【转】SQL行列转换
阅读量:6575 次
发布时间:2019-06-24

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

原文地址:
 
行列转换等经典SQL语句

1.--行列转换

原表:   姓名     科目   成绩
           张三     语文    80
           张三     数学    90
           张三     物理    85
           李四     语文    85
           李四     物理    82
           李四     英语    90
           李四     政治    70
           王五     英语    90

转换后的表:  姓名       数学    物理     英语    语文    政治 

                       李四         0         82        90      85       70
                       王五         0          0         90       0         0
                       张三        90        85         0       80        0

实例:

create table cj  --创建表cj
(
    ID       Int IDENTITY (1,1)     not null, --创建列ID,并且每次新增一条记录就会加1
    Name     Varchar(50),   
    Subject  Varchar(50),
    Result   Int,  
    primary key (ID)      --定义ID为表cj的主键      
);
--Truncate table cj
--Select * from cj
Insert into cj
Select '张三','语文',80 union all 
Select '张三','数学',90 union all
Select '张三','物理',85 union all
Select '李四','语文',85 union all
Select '李四','物理',82 union all
Select '李四','英语',90 union all
Select '李四','政治',70 union all
Select '王五','英语',90
--行列转换
Declare @sql varchar(8000)
Set @sql = 'Select Name as 姓名'
Select @sql = @sql + ',sum(case Subject when '''+Subject+''' then Result else 0 end) ['+Subject+']'
from (select distinct Subject from cj) as cj  --把所有唯一的科目的名称都列举出来
Select @sql = @sql+' from cj group by name'
Exec (@sql)

2. 行列转换--合并
原表:   班级    学号     
            1          1  
            1          2
            1          3
            2          1
            2          2
            3          1
转换后的表:  班级  学号            
                       1   1,2,3
                       2   1,2
                       3   1  

实例:

Create table ClassNo  --创建表ClassNo
(
    ID Int IDENTITY(1,1)  not null,  --创建列ID,并且每次新增一条记录就会加1
    Class  Varchar(50),    --班级列
    Number Varchar(50),    --学号列
    Primary Key(ID)        --定义ID为表ClassNo的主键
);
--Truncate Table ClassNo
--Select * from ClassNo
Insert Into ClassNo
Select 1,1 Union all
Select 1,2 Union all
Select 1,3 Union all
Select 2,1 Union all
Select 2,2 Union all
Select 3,1

创建一个合并的函数

--Drop Function KFReturn
Create Function KFReturn(@Class Varchar(50))
Returns Varchar(8000)
as 
Begin
Declare @str Varchar(8000)
Set @str = ''
Select @str = @str + cast(Number as Varchar(50))  + ',' from ClassNo Where Class = @Class 
Set @str = SubString(@str,1,len(@str)-1)
Return(@str)
End

--调用自定义函数得到结果

Select Distinct Class,dbo.KFReturn(Class) From ClassNo

3:列转行
--Drop Table ColumnToRow
Create table ColumnToRow
(
   ID Int IDENTITY(1,1)  not null,  --创建列ID,并且每次新增一条记录就会加1
   a  int,
   b  int,
   c  int,
   d  int,
   e  int,
   f  int,
   g  int,
   h  int,
   Primary Key(ID)        --定义ID为表ColumnToRow的主键      
);
--Truncate Table ColumnToRow 
--Select * from ColumnToRow
Insert Into ColumnToRow 
Select 15,9,1,0,1,2,4,2 Union all
Select 22,34,44,5,6,7,8,7 Union all
Select 33,44,55,66,77,88,99,12

Declare @sql Varchar(8000)

Set @sql = ''
Select @sql = @sql + rtrim(name) + ' from ColumnToRow union all Select ' from SysColumns Where id = object_id('ColumnToRow')
Set @sql = SubString(@sql,1,len(@sql)-70)
--70的长度就是这个字符串'from ColumnToRow union all Select ID from ColumnToRow union all Select ',因为它会把ID这一列的值也算进去,所以要把它截掉
Exec ('Select ' + @sql + ' from ColumnToRow')

4. 如何取得一个数据表的所有列名
方法如下:先从sysobjects系统表中取得数据表的systemid,然后再syscolumns表中取得该数据表的所有列名。
SQL语句如下:
Declare @objid int,@objname char(40)
set @objname = 'ColumnToRow'
--第1种方法
select @objid = id from sysobjects where id = object_id(@objname)
select 'Column_name' = name from syscolumns where id = @objid order by colid
--或也可以写成
select name as 'Column_name' from syscolumns where id = @objid order by colid
--第2种方法:
Select name as 'Column_Name' from SysColumns where id = object_id(@objname) Order by colid

5. 通过SQL语句来更改用户的密码

修改别人的,需要sysadmin role 
Exec Sp_password '原始密码','更改后密码','账号'
Exec sp_password null,ok,sa

6. 怎么判断出一个表的哪些字段不允许为空?

Declare @objname Varchar(50)
set @objname = 'ColumnToRow'
Select Column_Name from information_schema.Columns where is_nullable = 'No' and Table_Name = @objname

7. 如何在数据库里找到含有相同字段的表?

a. 查已知列名的情况
Select a.name as Columnname,b.name as tablename from SysColumns a inner join sysobjects b on a.id = b.id
and b.type = 'U' and a.name = '您要查找的字段名'
b. 未知列名查所有在不同表出现过的列名
Select s.name as tablename,s1.name as columnname from SysColumns s1,Sysobjects s 
Where s1.id = s.id and s.Type = 'U' and Exists (Select 1 from syscolumns s2 where s1.name = s2.name and s1.id <> s2.id)

8.查询第N行数据

假设id是主键: 
select * 
from (select top N * from 表) aa 
where not exists(select 1 from (select top N-1 * from 表) bb where aa.id=bb.id)

9. SQL Server日期计算

a. 一个月的第一天
SELECT DATEADD(mm, DATEDIFF(mm,0,getdate()), 0) 
b. 本周的星期一
SELECT DATEADD(wk, DATEDIFF(wk,0,getdate()), 0) 
c. 一年的第一天
SELECT DATEADD(yy, DATEDIFF(yy,0,getdate()), 0) 
d. 季度的第一天
SELECT DATEADD(qq, DATEDIFF(qq,0,getdate()), 0) 
e. 上个月的最后一天 
SELECT dateadd(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate()), 0)) 
f. 去年的最后一天
SELECT dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate()), 0)) 
g. 本月的最后一天
SELECT dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,getdate())+1, 0)) 
h. 本月的第一个星期一
select DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,6-datepart(day,getdate()),getdate())), 0) 
i. 本年的最后一天
SELECT dateadd(ms,-3,DATEADD(yy, DATEDIFF(yy,0,getdate())+1, 0))

如果认为此文对您有帮助,别忘了支持一下哦!

作者:
来源:
声明:本博客原创文字只代表本人工作中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未授权,贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。
转载:http://www.cnblogs.com/youring2/archive/2012/05/25/2517956.html
你可能感兴趣的文章
怎么给电脑设置IP地址和DNS地址,各系统设置IP/DNS几种方法
查看>>
java 面试题解惑二 到底创建了几个String对象?
查看>>
面试总结之 oop desing 之 The Strategy Pattern
查看>>
必 备 习 题 集 (一)
查看>>
第 三 十 四 天:二 阶 段 复 习(五)
查看>>
windows下批量部署简易脚本
查看>>
python爬虫入门—统计豆瓣电影评论词频
查看>>
mysql由于server-id相同而造成同步失败
查看>>
【LoadRunner技术讲座4】利用sitescope监测监控mysql
查看>>
IEnumerable中运用yield
查看>>
python 时间转换(day,hous,minute,second)
查看>>
网络布线线材用量计算公式
查看>>
查询当前数据库用户会话信息
查看>>
创建触发器的基本语法
查看>>
2015.1.15 利用Oracle函数返回表结果 重大技术进步!
查看>>
2015.3.2 VC++6制作非MFC dll以及VS2005、VS2010调用
查看>>
转:模态对话框的支持 (IE,Firefox,Chrome)
查看>>
让您的电脑在任意目录可以支持图片的粘贴,试试看呗~
查看>>
Jenkins+QTP自动化测试框架
查看>>
文件下载
查看>>