文:李慧
写程序,自然少不了跟数据库打交道。SQL似乎一直都倍受青睐。记得刚接触SQL的时候,经常会记不住函数的用法,或是语法出现错误,但自己却毫无意识。以下是整理的十项简单、基础的小事例,希望对刚踏上SQL之路的朋友有点儿帮助。
事例一:排序
(1) ORDER BY子句可包括未出现在此选择列表的项目.然而,如果指定SELECT DISTINCT,则排序列必定出现在选择列表中.
错误的语句:
SELECT DISTINCT 书名
FROM tb_BookStore
ORDER BY tb_BookCount
正确的语句:
SELECT DISTINCT (书名), tb_BookCount
FROM tb_BookStore
ORDER BY tb_BookCount
(2) Create Table #TEST
(
ID INT ,
gold INT , --等级
expire_date DATETIME --到期时间
)
Insert #TEST SELECT 1,2, ‘2006-06-30 ‘
Union All SELECT 2,3, ‘2006-06-30 ‘
Union All SELECT 3,5, ‘2006-05-30 ‘
Union All SELECT 4,6, ‘2006-06-12 ‘
Union All SELECT 5,10, ‘2006-07-30 ‘
Union All SELECT 6,1, ‘2006-08-30 ‘
Union All SELECT 6,1, ‘2008-08-30 ‘
Union All SELECT 6,1, ‘2009-08-30 ‘
现在要做的一个查询要求是:过期的无论等级是多少都要到后面显示,而没过期的还是正常按等级及到期时间排列。
SELECT * FROM [#TEST] ORDER BY
(CASE
When expire_date >= GetDate() Then 0 Else 1
End),
gold DESC ,expire_date DESC
事例2:CASE WHER
CASE 具有两种格式:
(1)简单 CASE 函数将某个表达式与一组简单表达式进行比较以确定结果。
(2)CASE搜索函数计算一组布尔表达式以确定结果。两种格式都支持可选的 ELSE参数。
简单CASE 函数
CASE input_expression
WHEN when_expression THEN result_expression
[ WHEN ...]
ELSE else_result_expression
END
CASE 搜索函数:
SELECT CASE StatusValue
WHEN ‘ 0 ‘ THEN (SELECT TOP 1 字段名 FROM work)
WHEN ‘ 1 ‘ THEN (SELECT TOP 1 字段名 FROM Notice)
END
FROM CommonStatusDict
事例3: DATEDIFF, 返回跨两个指定日期的日期和时间边界数 。
下面的 例 子 确定在 pubs 数据库中标题发布日期和当前日期间的 天 数。
USE pubs
GO
SELECT DATEDIFF(day, pubdate, getdate()) AS no_of_days
FROM titles
GO
事例4:CONVERT
CONVERT 的使用方法 :
格式 :
CONVERT(data_type,expression[,style])
说明 :
此样式一般在时间类型 (datetime,smalldatetime) 与字符串类型 (nchar,nVARCHAR,char,VARCHAR)
相互转换的时候才用到.
例子:
SELECT CONVERT(VARCHAR(30),getdate(),101) now
结果为
now
---------------------------------------
09/15/2001
例如当前时间为:2005-9-12 13:20:00
我要取其中的:2005-9-12
SELECT CONVERT (char(10), ‘2005-9-12 13:20:00 ‘,120)
事例5:STUFF 替换
比如 titles表中有id,name ,age 3个字段,我想根据name字段来修改id字段,并且在id字段前面添加 ‘ ABC ‘
UPDATE 表名 SET id=STUFF(id,1,3, ‘ abc ‘ ) WHERE name= ‘ 名称 ‘
事例6;连接字段输出
SELECT Name,Description FROM Students.现在我想把Name,Description作为一个字段Detail输出:
SELECT Name+Description AS Detail FROM Students
事例7;拷贝表格
建立表格: (新表,旧表)
CREATE TABLE table_old
(
ID int,
名称 NVARCHAR(30),
备注 NVARCHAR(1000)
)
INSERT tb (ID,名称,备注)VALUES(1, ‘ DDD ‘ ,1)
INSERT tb (ID,名称,备注)VALUES(1, ‘ 5100 ‘ , ‘ D ‘ )
INSERT tb (ID,名称,备注)VALUES(1, ‘ 5200 ‘ , ‘ E ‘ )
CREATE TABLE table_new
(
ID int,
名称 NVARCHAR(30),
备注 NVARCHAR(1000)
)
如上所示,表table_new的字段和顺序和表table_old 完全一样
拷贝语句:INSERT INTO table_new SELECT * FROM table_old
如果表格的字段跟顺序不一样,修改对应字段即可,注意插入数据主键问题。假如table_new与
table_old的id都是设为自动增长的,则是以下的写法:
INSERT INTO table_new( 名称 , 备注 )
SELECT 名称 , 备注 FROM table_old
或者 ,如果数据库中不存在table_new表 ,很简单 :
SELECT * INTO table_new FROM table_old
事例8:UNION 联合查询
SELECT * FROM A
UNION
SELECT * FROM B
--不合并重复行
SELECT * FROM A
UNION ALL
SELECT * FROM B
--如果要对字段进行排序
SELECT *
FROM (
SELECT id,... FROM A
UNION ALL
SELECT id,... FROM B
) t
ORDER BY ID
事例9:模糊查询
只要满足字符串中包含A或者B或者AB就选出,顺序不限,这样会选出很多
例:SELECT * FROM 表 WHERE 字段like ‘ %[AB]% ‘ 这样会选出如下组合
AB / BA / 所有包含A字母的数据 / 所有包含A字母的数据 / 所有包含AB字母的数据 /
所有包含BA字母的数据
事例10:动态SQL语句
动态SQL语句基本语法
1 :普通SQL语句可以用EXEC执行
eg: SELECT * FROM tableName
EXEC(SELECT * FROM tableName ‘)
EXEC sp_EXECutesql N ‘ SELECT * FROM tableName ‘
-- 请注意字符串前一定要加N
2:字段名,表名,数据库名之类作为变量时,必须用动态SQL
eg:
DECLARE @fname VARCHAR (20)
SET @fname = ‘FiledName ‘
SELECT @fname FROM tableName
--错误,不会提示错误,但结果为固定值FiledName,并非所要。
EXEC ( ‘ SELECT ‘ + @fname + ‘ FROM tableName ‘ )
--请注意加号前后的单引号的边上加空格
当然将字符串改成变量的形式也可
DECLARE @fname VARCHAR (20)
SET @fname = ‘ FiledName ‘ --设置字段名
DECLARE @s VARCHAR (1000)
SET @s = ‘ SELECT ‘ + @fname + ‘ FROM tableName ‘
EXEC (@s) --成功
EXEC sp_EXECutesql @s --此句会报错
DECLARE @s NVARCHAR (1000) --注意此处改为NVARCHAR (1000)
SET @s = ‘ SELECT ‘ + @fname + ‘ FROM tableName’
EXEC (@s) --成功
EXEC sp_EXECutesql @s --此句正确
3. 输出参数
DECLARE @num int,
@sqls nVARCHAR(4000)
SET @sqls= ‘SELECT count(*) FROM tableName’
EXEC(@sqls)
--如何将EXEC执行结果放入变量中?
DECLARE @num INT ,
@sqls N VARCHAR(4000)
SET @sqls= ‘SELECT @a=count(*) FROM tableName ‘
EXEC sp_EXECutesql @sqls,N ‘@a INT OUTPUT ‘,@num OUTPUT
SELECT @num
最后,谢谢你的耐心^_^!一路的点滴苦痛,原来,都是收获。

