记录生活
标签 Tag : SQL

[转] SQL优化心得

<Category: SQL Server> 发表评论

大家都在讨论关于数据库优化方面的东东,刚好参与开发了一个数据仓库方面的项目,以下的一点东西算是数据库优化方面的学习+实战的一些心得体会了,拿出来大家共享。欢迎批评指正阿!

SQL语句:
是对数据库(数据)进行操作的惟一途径;
消耗了70%~90%的数据库资源;独立于程序设计逻辑,相对于对程序源代码的优化,对SQL语句的优化在时间成本和风险上的代价都很低;
可以有不同的写法;易学,难精通。

SQL优化:
固定的SQL书写习惯,相同的查询尽量保持相同,存储过程的效率较高。
应该编写与其格式一致的语句,包括字母的大小写、标点符号、换行的位置等都要一致

ORACLE优化器:
在任何可能的时候都会对表达式进行评估,并且把特定的语法结构转换成等价的结构,这么做的原因是
要么结果表达式能够比源表达式具有更快的速度
要么源表达式只是结果表达式的一个等价语义结构
不同的SQL结构有时具有同样的操作(例如:= ANY (subquery) and IN (subquery)),ORACLE会把他们映射到一个单一的语义结构。

阅读这篇文章的其余部分 »

本文来自: [转] SQL优化心得

多个字段排序的sql

<Category: SQL Server> 发表评论

sql又生疏了...

CREATE TABLE testsort(
 a varchar,
 b varchar,
 c varchar)
--需要按照b,c排序,按照a来分组,b降序,c升序,每个A组里面取排序后的第一条记录
INSERT INTO testsort VALUES('A','1','2');
INSERT INTO testsort VALUES('A','3','2');
INSERT INTO testsort VALUES('A','3','1');
INSERT INTO testsort VALUES('B','3','2');
INSERT INTO testsort VALUES('B','2','1');
INSERT INTO testsort VALUES('C','1','2');
INSERT INTO testsort VALUES('C','1','4');
 
SELECT * FROM testsort;
 
SELECT   *, identity(int,1,1) AS id
 INTO #temp
FROM testsort ORDER BY a,b,c,id
 
SELECT * FROM #temp;
 
SELECT f.a,f.b,f.c FROM ( SELECT a,max(id) AS id FROM #temp as d group by d.a) as d   --use minx(id) as you wish
 
LEFT JOIN #temp f on d.id=f.id

Untitled

SQL的identity函数只有在select into时才可用;
DB2 的自增列函数 ROW_NUMBER() OVER() ;

本文来自: 多个字段排序的sql

SQL条件处理--Case语句

<Category: SQL Server> 发表评论

SQL中使用CASE处理条件

     在使用SQL的过程中,有时候可能会要对数据进行条件查询。比如字段A为True时查询出“男”,否则查询出“女”。这样就可以不在程序中在去判断了。在SQL中,可以利用Case语句来完成这样的查询。

一、Case介绍

CASE
计算条件列表并返回多个可能结果表达式之一。

CASE 具有两种格式:

简单 CASE 函数将某个表达式与一组简单表达式进行比较以确定结果。
CASE 搜索函数计算一组布尔表达式以确定结果。
两种格式都支持可选的 ELSE 参数。

语法
简单 CASE 函数:

CASE input_expression
    WHEN when_expression THEN result_expression
        [ ...n ]
    [
        ELSE else_result_expression
    END

CASE 搜索函数:

CASE
    WHEN Boolean_expression THEN result_expression
        [ ...n ]
    [
        ELSE else_result_expression
    END

参数
input_expression

是使用简单 CASE 格式时所计算的表达式。Input_expression 是任何有效的 Microsoft® SQL Server™ 表达式。

WHEN when_expression

使用简单 CASE 格式时 input_expression 所比较的简单表达式。When_expression 是任意有效的 SQL Server 表达式。Input_expression 和每个 when_expression 的数据类型必须相同,或者是隐性转换。

n

占位符,表明可以使用多个 WHEN when_expression THEN result_expression 子句或 WHEN Boolean_expression THEN result_expression 子句。

THEN result_expression

当 input_expression = when_expression 取值为 TRUE,或者 Boolean_expression 取值为 TRUE 时返回的表达式。result expression 是任意有效的 SQL Server 表达式。

ELSE else_result_expression

当比较运算取值不为 TRUE 时返回的表达式。如果省略此参数并且比较运算取值不为 TRUE,CASE 将返回 NULL 值。Else_result_expression 是任意有效的 SQL Server 表达式。Else_result_expression 和所有 result_expression 的数据类型必须相同,或者必须是隐性转换。

WHEN Boolean_expression

使用 CASE 搜索格式时所计算的布尔表达式。Boolean_expression 是任意有效的布尔表达式。

二、SQL中的Case语句实例

    CASE 函数用于计算多个条件并为每个条件返回单个值。CASE 函数通常的用途是使用可读性更强的值替换代码或缩写。下面的查询使用 CASE 函数重命名书籍的分类,以使之更易理解。

USE pubs
SELECT
   CASE type
      WHEN 'popular_comp' THEN 'Popular Computing'
      WHEN 'mod_cook' THEN 'Modern Cooking'
      WHEN 'business' THEN 'Business'
      WHEN 'psychology' THEN 'Psychology'
      WHEN 'trad_cook' THEN 'Traditional Cooking'
      ELSE 'Not yet categorized'
   END AS Category,
CONVERT(varchar(30), title) AS "Shortened Title",
price AS Price
FROM titles
WHERE price IS NOT NULL
ORDER BY 1

下面是结果集:

category            shortened title                Price �
------------------- ------------------------------ -------
Business            Cooking with Computers: Surrep 11.95 �
Business            Straight Talk About Computers  19.99 �
Business            The Busy Executive's Database  19.99 �
Business            You Can Combat Computer Stress 2.99  �
Modern Cooking      Silicon Valley Gastronomic Tre 19.99 �
Modern Cooking      The Gourmet Microwave          2.99  �
Popular Computing   But Is It User Friendly?       22.95 �
Popular Computing   Secrets of Silicon Valley      20.00 �
Psychology          Computer Phobic AND Non-Phobic 21.59 �
Psychology          Emotional Security: A New Algo 7.99  �
Psychology          Is Anger the Enemy?            10.95 �
Psychology          Life Without Fear              7.00  �
Psychology          Prolonged Data Deprivation: Fo 19.99 �
Traditional Cooking Fifty Years in Buckingham Pala 11.95 �
Traditional Cooking Onions, Leeks, and Garlic: Coo 20.95 �
Traditional Cooking Sushi, Anyone?                 14.99  

(16 row(s) affected)

CASE 函数的另一个用途给数据分类。下面的查询使用 CASE 函数对价格分类。

SELECT
   CASE
      WHEN price IS NULL THEN 'Not yet priced'
      WHEN price < 10 THEN 'Very Reasonable Title'
      WHEN price >= 10 and price < 20 THEN 'Coffee Table Title'
      ELSE 'Expensive book!'
   END AS "Price Category",
CONVERT(varchar(20), title) AS "Shortened Title"
FROM pubs.dbo.titles
ORDER BY price

下面是结果集:

Price Category        Shortened Title    �
--------------------- --------------------
Not yet priced        The Psychology of Co
Not yet priced        Net Etiquette      �
Very Reasonable Title You Can Combat Compu
Very Reasonable Title The Gourmet Microwav
Very Reasonable Title Life Without Fear  �
Very Reasonable Title Emotional Security:�
Coffee Table Title    Is Anger the Enemy?�
Coffee Table Title    Cooking with Compute
Coffee Table Title    Fifty Years in Bucki
Coffee Table Title    Sushi, Anyone?     �
Coffee Table Title    The Busy Executive's
Coffee Table Title    Straight Talk About�
Coffee Table Title    Silicon Valley Gastr
Coffee Table Title    Prolonged Data Depri
Expensive book!       Secrets of Silicon V
Expensive book!       Onions, Leeks, and G
Expensive book!       Computer Phobic AND�
Expensive book!       But Is It User Frien

(18 row(s) affected)

本文来自: SQL条件处理--Case语句

SET PARSEONLY 与SET NOEXEC (Transact-SQL)

<Category: SQL Server> 发表评论

SET PARSEONLY
检查每个 Transact-SQL 语句的语法并返回任何错误消息,但不编译和执行语句。
SET PARSEONLY { ON | OFF }

当 SET PARSEONLY 为 ON 时,SQL Server 只分析语句。当 SET PARSEONLY 为 OFF 时,SQL Server 编译并执行语句。

SET PARSEONLY 的设置是在分析时设置,而不是在执行或运行时设置。

在存储过程或触发器中不要使用 PARSEONLY。如果 OFFSETS 选项为 ON 而且没有出现错误,则 SET PARSEONLY 返回偏移量。

SET NOEXEC (Transact-SQL)

编译每个查询但不执行查询。
SET NOEXEC { ON | OFF }
当 SET NOEXEC 为 ON 时,SQL Server 将编译每一批处理 Transact-SQL 语句但并不执行它们。当 SET NOEXEC 设置为 OFF 时,所有批处理将在编译后执行。

SQL Server 中的语句执行包含两个阶段:编译和执行。该设置可用于让 SQL Server 在执行 Transact-SQL 代码时,验证代码中的语法和对象名。它也可以用于调试通常是较大的批处理中的部分语句。

SET NOEXEC 设置是在执行或运行时设置,而不是在分析时设置。

 

USE AdventureWorks;
GO
PRINT 'Valid query';
GO
-- SET NOEXEC to ON.
SET NOEXEC ON;
GO
-- Inner join.
SELECT e.EmployeeID, e.Title, v.Name
FROM HumanResources.Employee e
INNER JOIN Purchasing.PurchaseOrderHeader poh
ON e.EmployeeID = poh.EmployeeID
INNER JOIN Purchasing.Vendor v
ON poh.VendorID = v.VendorID;
GO
-- SET NOEXEC to OFF.
SET NOEXEC OFF;
GO

PRINT 'Invalid object name';
GO
-- SET NOEXEC to ON.
SET NOEXEC ON;
GO
-- Function name used is a reserved keyword.
USE AdventureWorks;
GO
CREATE FUNCTION dbo.Values(@EmployeeID INT)
RETURNS TABLE
AS
RETURN (SELECT PurchaseOrderID, TotalDue
FROM dbo.PurchaseOrderHeader
WHERE EmployeeID = @EmployeeID)
-- SET NOEXEC to OFF.
SET NOEXEC OFF
GO

PRINT 'Invalid syntax';
GO
-- SET NOEXEC to ON.
SET NOEXEC ON;
GO
-- Built-in function incorrectly invoked
SELECT *
FROM fn_helpcollations;
-- Reset SET NOEXEC to OFF.
SET NOEXEC OFF;
GO

本文来自: SET PARSEONLY 与SET NOEXEC (Transact-SQL)

从数据库随机读取数据

<Category: SQL Server> 发表评论

示例代码:
SQL Server:Select Top * From  表 Order By NewID()  
Access  :Select Top * From 表 Order By Rnd(ID) 
        *说明-Rnd(ID) 其中的ID是自动编号字段,可以利用其他任何数值来完成,比如用姓名字段(UserName)  Select Top 10 * From 表 Order BY Rnd(Len(UserName))
 
MySql:Select * From 表 Order By Rand() Limit 10

本文来自: 从数据库随机读取数据

T-SQL象数组一样处理字符串、分割字符串

<Category: SQL Server> 发表评论

    在日常的编程过程中,数组是要经常使用到的。在利用SQL对数据库进行操作时,有时就想在SQL使用数组,比如将1,2,3,4,5拆分成数组。可惜的是在T-SQL中不支持数组。不过还是有变通的办法。我们可以自己编写两函数Get_StrArrayLength(取得字符串的长度-元素的个数)和Get_StrArrayStrOfIndex(按指定符号分割字符串,返回分割后指定索引的第几个元素)。有了这两个函数,我们就可以非常方便的在T-SQL中处理形如1,2,3,4,5这样的字符串了。 

    T-SQL对字符串的处理能力比较弱,比如我要循环遍历象1,2,3,4,5这样的字符串,如果用数组的话,遍历很简单,但是T-SQL不支持数组,所以处理下来比较麻烦。下边的函数,实现了象数组一样去处理字符串。 

一、按指定符号分割字符串,返回分割后的元素个数,方法很简单,就是看字符串中存在多少个分隔符号,然后再加一,就是要求的结果。
CREATE function Get_StrArrayLength
(
 @str varchar(1024),  --要分割的字符串
 @split varchar(10)  --分隔符号
)
returns int
as
 begin
  declare @location int
  declare @start int
  declare @length int
  set @str=ltrim(rtrim(@str))
  set @location=charindex(@split,@str)
  set @length=1
   while @location<>0
     begin
      set @start=@location+1
      set @location=charindex(@split,@str,@start)
      set @length=@length+1
     end
   return @length
 end

调用示例:select dbo.Get_StrArrayLength('78,1,2,3',',')

返回值:4

 

二、按指定符号分割字符串,返回分割后指定索引的第几个元素,象数组一样方便

CREATE function Get_StrArrayStrOfIndex
(
 @str varchar(1024),  --要分割的字符串
 @split varchar(10),  --分隔符号
 @index int --取第几个元素
)
returns varchar(1024)
as
begin
 declare @location int
 declare @start int
 declare @next int
 declare @seed int
 set @str=ltrim(rtrim(@str))
 set @start=1
 set @next=1
 set @seed=len(@split)
 set @location=charindex(@split,@str)
 while @location<>0 and @index>@next
   begin
    set @start=@location+@seed
    set @location=charindex(@split,@str,@start)
    set @next=@next+1
   end
 if @location =0 select @location =len(@str)+1

--这儿存在两种情况:1、字符串不存在分隔符号 2、字符串中存在分隔符号,跳出while循环后,@location为0,那默认为字符串后边有一个分隔符号。
 return substring(@str,@start,@location-@start)
end

调用示例:select dbo.Get_StrArrayStrOfIndex('8,9,4',',',2)

返回值:9

 

三、结合上边两个函数,象数组一样遍历字符串中的元素

 declare @str varchar(50)
 set @str='1,2,3,4,5'
 declare @next int
 set @next=1
 while @next<=dbo.Get_StrArrayLength(@str,',')
   begin
     print dbo.Get_StrArrayStrOfIndex(@str,',',@next)
     set @next=@next+1
   end

 调用结果:
1
2
3
4
5

本文来自: T-SQL象数组一样处理字符串、分割字符串

常用SQL字符串函数问题集锦

<Category: SQL Server> 发表评论

SQL字符串函数
字符串函数对二进制数据、字符串和表达式执行不同的运算。此类函数作用于CHAR、VARCHAR、 BINARY、 和VARBINARY 数据类型以及可以隐式转换为CHAR 或VARCHAR的数据类型。可以在SELECT 语句的SELECT 和WHERE 子句以及表达式中使用字符串函数。常用的字符串函数有:

一、字符转换函数
1、ASCII()
返回字符表达式最左端字符的ASCII 码值。在ASCII()函数中,纯数字的字符串可不用‘’括起来,但含其它字符的字符串必须用‘’括起来使用,否则会出错。 

2、CHAR()
将ASCII 码转换为字符。如果没有输入0 ~ 255 之间的ASCII 码值,CHAR() 返回NULL 。 

3、LOWER()和UPPER()
LOWER()将字符串全部转为小写;UPPER()将字符串全部转为大写。

 4、STR()
把数值型数据转换为字符型数据。
STR (<float_expression>[,length[, <decimal>]])
length 指定返回的字符串的长度,decimal 指定返回的小数位数。如果没有指定长度,缺省的length 值为10, decimal 缺省值为0。
当length 或者decimal 为负值时,返回NULL;
当length 小于小数点左边(包括符号位)的位数时,返回length 个*;
先服从length ,再取decimal ;
当返回的字符串位数小于length ,左边补足空格。

 二、去空格函数
1、LTRIM() 把字符串头部的空格去掉。

2、RTRIM() 把字符串尾部的空格去掉。

三、取子串函数
1、left()
LEFT (<character_expression>, <integer_expression>)
返回character_expression 左起 integer_expression 个字符。

2、RIGHT()
RIGHT (<character_expression>, <integer_expression>)
返回character_expression 右起 integer_expression 个字符。

3、SUBSTRING()
SUBSTRING (<expression>, <starting_ position>, length)
返回从字符串左边第starting_ position 个字符起length个字符的部分。

四、字符串比较函数
1、CHARINDEX()
返回字符串中某个指定的子串出现的开始位置。
CHARINDEX ( expression1 ,expression2 [ , start_location ] )
其中substring _expression 是所要查找的字符表达式,expression 可为字符串也可为列名表达式。如果没有发现子串,则返回0 值。
此函数不能用于TEXT 和IMAGE 数据类型。

 2、PATINDEX()
返回字符串中某个指定的子串出现的开始位置。
PATINDEX (<’%substring _expression%’>, <column_ name>)其中子串表达式前后必须有百分号“%”否则返回值为0。
与CHARINDEX 函数不同的是,PATINDEX函数的子串中可以使用通配符,且此函数可用于CHAR、 VARCHAR 和TEXT 数据类型。

五、字符串操作函数
1、QUOTENAME()
返回被特定字符括起来的字符串。
QUOTENAME (<’character_expression’>[, quote_ character]) 其中quote_ character 标明括字符串所用的字符,缺省值为“[]”。

 2、REPLICATE()
返回一个重复character_expression 指定次数的字符串。
REPLICATE (character_expression integer_expression) 如果integer_expression 值为负值,则返回NULL 。

3、REVERSE()
将指定的字符串的字符排列顺序颠倒。
REVERSE (<character_expression>) 其中character_expression 可以是字符串、常数或一个列的值。

4、REPLACE()
返回被替换了指定子串的字符串。
REPLACE (<string_expression1>, <string_expression2>, <string_expression3>) 用string_expression3 替换在string_expression1 中的子串string_expression2。

4、SPACE()
返回一个有指定长度的空白字符串。
SPACE (<integer_expression>) 如果integer_expression 值为负值,则返回NULL 。

5、STUFF()
用另一子串替换字符串指定位置、长度的子串。
STUFF (<character_expression1>, <start_ position>, <length>,<character_expression2>)
如果起始位置为负或长度值为负,或者起始位置大于character_expression1 的长度,则返回NULL 值。
如果length 长度大于character_expression1 中 start_ position 以右的长度,则character_expression1 只保留首字符。

 六、数据类型转换函数
1、CAST()
CAST (<expression> AS <data_ type>[ length ])

2、CONVERT()
CONVERT (<data_ type>[ length ], <expression> [, style])

1)data_type为SQL Server系统定义的数据类型,用户自定义的数据类型不能在此使用。
2)length用于指定数据的长度,缺省值为30。
3)把CHAR或VARCHAR类型转换为诸如INT或SAMLLINT这样的INTEGER类型、结果必须是带正号或负号的数值。
4)TEXT类型到CHAR或VARCHAR类型转换最多为8000个字符,即CHAR或VARCHAR数据类型是最大长度。
5)IMAGE类型存储的数据转换到BINARY或VARBINARY类型,最多为8000个字符。
6)把整数值转换为MONEY或SMALLMONEY类型,按定义的国家的货币单位来处理,如人民币、美元、英镑等。
7)BIT类型的转换把非零值转换为1,并仍以BIT类型存储。
8)试图转换到不同长度的数据类型,会截短转换值并在转换值后显示“+”,以标识发生了这种截断。
9)用CONVERT() 函数的style 选项能以不同的格式显示日期和时间。style 是将DATATIME 和SMALLDATETIME 数据转换为字符串时所选用的由SQL Server 系统提供的转换样式编号,不同的样式编号有不同的输出格式。

  七、日期函数
1、day(date_expression)
返回date_expression中的日期值

2、month(date_expression)
返回date_expression中的月份值

3、year(date_expression)
返回date_expression中的年份值

4、DATEADD()
DATEADD (<datepart>, <number>, <date>)
返回指定日期date 加上指定的额外日期间隔number 产生的新日期。参数“datepart” 取值如下:

 5、DATEDIFF()
DATEDIFF (<datepart>, <date1>, <date2>)
返回两个指定日期在datepart 方面的不同之处,即date2 超过date1的差距值,其结果值是一个带有正负号的整数值。

6、DATENAME()
DATENAME (<datepart>, <date>)
以字符串的形式返回日期的指定部分此部分。由datepart 来指定。

7、DATEPART()
DATEPART (<datepart>, <date>)
以整数值的形式返回日期的指定部分。此部分由datepart 来指定。
DATEPART (dd, date) 等同于DAY (date)
DATEPART (mm, date) 等同于MONTH (date)
DATEPART (yy, date) 等同于YEAR (date)

8、GETDATE()
以DATETIME 的缺省格式返回系统当前的日期和时间

本文来自: 常用SQL字符串函数问题集锦

SQL:获取不同版本中差异参数值

<Category: SQL Server> 发表评论

帮朋友写的一个sql,比较数据里面不同版本的参数数值

阅读这篇文章的其余部分 »

本文来自: SQL:获取不同版本中差异参数值

SET QUOTED_IDENTIFIER

<Category: 数据库> 发表评论

SET QUOTED_IDENTIFIER
使 Microsoft® SQL Server™ 遵从关于引号分隔标识符和文字字符串的 SQL-92 规则。由双引号分隔的标识符可以是 Transact-SQL 保留关键字,或者可以包含 Transact-SQL 标识符语法规则通常不允许的字符。

阅读这篇文章的其余部分 »

本文来自: SET QUOTED_IDENTIFIER

SQL函数大全及用法

<Category: SQL Server, 数据库> 5 条评论

--聚合函数
use pubs
go
select avg(distinct price) --算平均数
from titles
where type='business'
go
use pubs
go
select max(ytd_sales) --最大数
from titles
go

use pubs
go
select min(ytd_sales) --最小数
from titles
go

use pubs
go
select type,sum(price),sum(advance) --求和
from titles
group by type
order by type
go

use pubs
go
select count(distinct city) --求个数
from authors
go

use pubs
go
select stdev(royalty) --返回给定表达式中所有值的统计标准偏差
from titles
go

阅读这篇文章的其余部分 »

本文来自: SQL函数大全及用法