SQL语句是一种集合操作,就是批量操作,它的速度要比其他的语言快,所以在设计的时候很多的逻辑都会放在sql语句或者存储过程中来实现,这个是一种设计思想。但是今天我们来讨论另外一个话题。Sql页提供了丰富的函数供我们使用,还有很多操作有意想不到的结果,今天这个随笔来看看一些不常见到的sql语句。这些语句不像普通的增删查那样平白,它的奇妙之处有时候让人另眼相看。

  

1.  假设我想把Person.Contact表中所有人的名字用逗号连接起来,串成一个字符串,可能会想到使用游标把FirstName查出来然后逐行赋值给一个字符串变量,可是使用游标的代价是很大的。看看下面的代码:

declare @names varchar(1000)=''—注意赋值为空字符串是必须的
select @names=isnull(@names,'')+FirstName+',' from Person.Contact
print @names

查询得到的结果是(用的是AdventureWorks数据库中的Contact表):Gustavo,Catherine,Kim,Humberto,Pilar,Frances,Margaret,Carla,Jay,Ronald,Samuel,James,Robert,Fran?ois,Kim,Lili,Amy,Anna,Milton,Paul,Gregory,J. Phillip,Michelle,Sean,Phyllis,Marvin,Michael,Cecil,Oscar,Sandra,Selena,Emilio,Maxwell,Mae,Ramona,Sabria,Hannah,Kyley,Tom,Thomas,John,Chris,

使用其他的语句是不能达到这个效果的,不过我没有深入考虑过,但是这个是很简单的语句。

还有一个地方和这个类似,就是在行列转换的时候拼接动态sql语句,首先使用下面的语句创建一个临时表:

 
create table #DepartCost
(
id int,
Department varchar(20),
Material varchar(20),
Number int
)
insert into #DepartCost values
(1,'厂房1','材料1',1),
(1,'厂房2','材料2',2),
(1,'厂房1','材料3',1),
(1,'厂房3','材料3',1),
(1,'厂房2','材料3',1),
(1,'厂房3','材料1',1),
(1,'厂房1','材料1',2),
(1,'厂房1','材料2',1),
(1,'厂房1','材料3',1)
 

表中的数据如下:

图1

我们看到每个厂房分别使用的材料数量,还是一个老问题,如果我们想知道针对每种材料,每个厂房耗费的材料数量是多少该怎么写呢。有一种笨的方法,如下:

select Department,
sum(case Material when '材料1' then Number else 0 end) as [材料1],
sum(case Material when '材料2' then Number else 0 end) as [材料2],
sum(case Material when '材料3' then Number else 0 end) as [材料3]
from #DepartCost
group by Department

查询结果如下:

图2

说这种方法笨是因为需要事先知道材料的类别,如果有很多种材料这个语句就会很长了,下面我们使用动态语句来实现这个功能:

declare @sql varchar(1000)
set @sql = 'select Department '
select @sql = @sql+', sum(case Material when '''+Material+''' then Number else 0 end) as ['+Material+']' from
(select distinct Material from #DepartCost) as a
select @sql = @sql + ' from #DepartCost group by Department '
exec(@sql)

我们来看看@sql字符串变量到底长得什么样子,使用print @sql将它打印出来:

select Department , sum(case Material when '材料' then Number else 0 end) as [材料], sum(case Material when '材料' then Number else 0 end) as [材料], sum(case Material when '材料' then Number else 0 end) as [材料] from #DepartCost group by Department

这个语句和上面那个是一样的,当然exec(@sql)得到的结果也是一样的了。这里我不知道这种特性有个什么说法,不像子查询,也不是case语句。

  

2.写一个语句获得当前这个月有多少天

这个涉及到日期和时间,初步的思路是查询得到本月的最后一天,然后用datepart获得天数,这是一个很直接的方法。来看下面的语句:

 
select 
datepart(
dd,--datepart的参数取本月最后一天的天数,即为本月的天数
dateadd(dd,--取下个月的第一天的前一天,就是本月最后一天
-1,
dateadd(mm,--取下一个月的第一天
1,
cast(cast(year(getdate())as varchar)+'-'+ --取当前的年
cast(month(getdate()) as varchar)+'-01'--取这个月的第一天
as datetime))) --转换成时间
)
 

这个语句没有什么悬念,仅仅是时间函数的使用,只要知道这个思路就很容易写出来。

  

3.假设我们有一张销售表,现在要查出销售单价,但是我们想不适用具体的价钱来显示,而是显示为一个范围,比如价钱是1-100元要显示“1 to 100”,100-200要显示“100 to 200”,等等。来看代码:

 
select so.UnitPrice, NewUnitPrice =  
case when so.UnitPrice is null then 'unknown' --NewPrice一点类似于C#里面的var变量,事先不定义类型,从赋值结果里面确认它的类型
when so.UnitPrice between 100 and 200 then '100 to 200'
when so.UnitPrice between 201 and 300 then '200 to 300'
when so.UnitPrice between 301 and 400 then '300 to 400'
else cast(so.UnitPrice as varchar(10)) --这里一定要转换成字符串
end
from Sales.SalesOrderDetail so order by UnitPrice
 

要注意的是最后剩下一些不做归类转换的必须将类型转换为varchar,否则会有语法错误。结果如下:

图3

  

4.假设有一张联系人姓名表,现在想查出这个表中姓相同的联系人的数目,猛一看有点懵,其实很简单,来看代码:

select c.LastName,num_LastName=COUNT(1) from Person.Contact c group by c.LastName

图4

注意要统计那个字段就要对那个字段进行聚合操作,如图我们可以看到有77个姓Davis的,71个姓Lin的,90个姓Waston的等等。

  

5.查找数据库中所有表的行数

 
select ROW_NUMBER() over(order by TABLE_NAME) as rownumber,TABLE_SCHEMA, TABLE_NAME into #table from INFORMATION_SCHEMA.TABLES where TABLE_TYPE='BASE TABLE'
declare @count int
select @count = COUNT(*) from #table
declare @index int = 1
declare @tablename nvarchar(200)
declare @sql nvarchar(1000)
while @index<@count
begin
select @tablename=TABLE_SCHEMA+'.'+TABLE_NAME from #table where rownumber=@index
select @sql= 'select '''+@tablename+''' as tablename, COUNT(*) as rowscount from '+ @tablename
exec (@sql)
if @index>@count
break
set @index = @index+1
end
drop table #table
 

这个方法很一般,求教高手们提供一个更加灵活的方法。

来源:http://www.cnblogs.com/tylerdonet/archive/2011/08/01/2124046.html

SQL几个有点偏的语句的更多相关文章

  1. SQL点滴21—几个有点偏的语句

    原文:SQL点滴21-几个有点偏的语句 SQL语句是一种集合操作,就是批量操作,它的速度要比其他的语言快,所以在设计的时候很多的逻辑都会放在sql语句或者存储过程中来实现,这个是一种设计思想.但是今天 ...

  2. SQL服务器在执行这条语句时会先进行运算然后执行

    1.打开地址,我们可以看到是一个正常的页面. 2..然后在地址后面加上-1,变成:http://site/news.asp?id=123-1,若返回的页面和前面不同,是另一个正常的页面,则表示存在注入 ...

  3. PL/SQL中批量执行SQL脚本(不可把所有的语句都复制到New SQL Windows)

    PL/SQL中批量执行SQL脚本,不可把所有的语句都复制到New SQL Window,因为这样会导致缓冲区过大而进程卡死! 最好的办法是将要执行的SQL脚本存放到指定文件中,如C:\insert.s ...

  4. 浅谈sql 、linq、lambda 查询语句的区别

    浅谈sql .linq.lambda 查询语句的区别 LINQ的书写格式如下: from 临时变量 in 集合对象或数据库对象 where 条件表达式 [order by条件] select 临时变量 ...

  5. SQL点滴1—SET QUOTED_IDENTIFIER OFF语句的作用

    原文:SQL点滴1-SET QUOTED_IDENTIFIER OFF语句的作用 先看下面几个sql语句 代码   SELECT * FROM [USER]    WHERE a= 'netasp' ...

  6. (数据科学学习手册28)SQL server 2012中的查询语句汇总

    一.简介 数据库管理系统(DBMS)最重要的功能就是提供数据查询,即用户根据实际需求对数据进行筛选,并以特定形式进行显示.在Microsoft SQL Serve 2012 中,可以使用通用的SELE ...

  7. 【SQL Server DBA】日常巡检语句3:特定监控(阻塞、top语句、索引、作业)

    原文:[SQL Server DBA]日常巡检语句3:特定监控(阻塞.top语句.索引.作业) 1.查询阻塞信息.锁定了哪些资源 --1.查看阻塞信息 select spid,loginame,wai ...

  8. 【SQL Server学习笔记】Delete 语句、Output 子句、Merge语句

    原文:[SQL Server学习笔记]Delete 语句.Output 子句.Merge语句 DELETE语句 --建表 select * into distribution from sys.obj ...

  9. SQL Server常用的性能诊断语句

    /* 常规服务器动态管理对象包括: dm_db_*:数据库和数据库对象 dm_exec_*:执行用户代码和关联的连接 dm_os_*:内存.锁定和时间安排 dm_tran_*:事务和隔离 dm_io_ ...

随机推荐

  1. WordPress Woopra plugin remote PHP arbitrary code execution exploit.

    测试方法: 提供程序(方法)可能带有攻击性,仅供安全研究与教学之用,风险自负! # Exploit Title: woopra plugins execute arbitrary PHP code E ...

  2. 计算几何(凸包):SHTSC 2012 信用卡凸包

    这道题是水题,发现平移某些边,答案就是圆心的凸包+一个圆的周长. 不要忽视精度误差! #include <algorithm> #include <iostream> #inc ...

  3. 在Eclipse中安装和使用TFS插件

    在Eclipse中安装插件的方法其实都一样,安装TFS的步骤如下: 下载TFS插件.你可以到微软的下载中心,下载TFS插件TFSEclipsePlugin-UpdateSiteArchive-10.0 ...

  4. substring 在C#,Javascript,SQL 中index开始值

    substring函数index参数在三个平台的开始值: 平台 index参数开始值 C# 0 Javascript 0 SQL 1

  5. JS中多个onload冲突解决办法

    一  多个window.onload冲突 在一个页面中有两个JavaScript 分别都用到了window.onload一个是:window.onload=externallinks,另一个是:win ...

  6. Mitmproxy首页、文档和下载 - 支持SSL的HTTP代理 - 开源中国社区

    Mitmproxy首页.文档和下载 - 支持SSL的HTTP代理 - 开源中国社区 undefined 利用Dnspod api批量更新添加DNS解析[python脚本] - 推酷 undefined

  7. C语言字节对齐 __align(),__attribute((aligned (n))),#pragma pack(n)

    转载地址 : http://blog.csdn.net/21aspnet/article/details/6729724 一.概念    对齐跟数据在内存中的位置有关.如果一个变量的内存地址正好位于它 ...

  8. tar打包和解压命令

    如果你有一个大文件 想下载下来 但是又太大 可以压缩一下 然后打包 #压缩 tar -czvf ***.tar.gz tar -cjvf ***.tar.bz2 #解压缩 tar -xzvf ***. ...

  9. linux中mysql完整卸载命令操作

    yum方式安装的mysql 1.yum remove mysql mysql-server mysql-libs compat-mysql51 2.rm -rf /var/lib/mysql3.rm ...

  10. 应用程序无法正常启动0xc0150002 解决方式

        我也遇到过此问题,解决的方法: 方案一: 在项目的"属性|配置属性|链接器|常规"中的"启用增量链接"选择"否".此方法阻断了问题产 ...