发布时间:2011-08-10 13:24 来源:未知
写在过去不久的文章里:最近在上海找工作,前前后后面试了N家单位,发现各个公司对程序员的数据库知识尤其是SQL语句的掌握程度有很高的要求,作为一名光荣的程序员,不会玩儿SQL语句走在街上根本不好意思和人打招呼!好了,废话不多说,新手菜鸟同志们了注意了,该文提供的例子很简单,但是也很重要,请认真练习!别等到面试的时候被某些人嘲讽"唉!这年头,会写SQL语句的程序员越来越少了!L"老鸟高手同志们,你们可以优雅地飘过,但是有什么意见或建议都要提出来哦,大家一起进步嘛J,让菜鸟变成高手,提高我国的编程水平。
1、DDL(数据定义语言)
1)创建数据表
--创建数据表 create table Test(Id int not null, Age char(20)); --创建数据表 create table T_Person1(Id int not null, Name nvarchar(50), Age int null); --创建表,添加外键 Create table T_Students( StudentNo char(4), CourseNo char(4), Score int, Primary key(StudentNo), Foreign key(CourseNo) References T_Course(CourseNo) );
2)修改表结构 --修改表结构,添加字段 Alter table T_Person add NickName nvarchar(50) null; --修改表结构,删除字段 Alter table T_Person Drop NickName;
3)删除数据表 --删除数据表 Drop table T_Person; --删除数据表 drop table test
4)创建索引 Create [Unique] Index <索引名> on <基本表名>(<列明序列>);
2、DML(数据操纵语言) -------------------------------------- -----数据汇总-聚合函数--------- -------------------------------------- --查询T_Employee表中数据条数 selectCOUNT(*)fromT_Employee --查询工资最高的人 selectMAX(FSalary)asTop1fromT_Employee --查询工资最低的人 selectMin(FSalary)asBottom1fromT_Employee --查询工资的平均水平 selectAvg(FSalary)as平均水平fromT_Employee --所有工资的和 selectSUM(FSalary)as总工资fromT_Employee --查询工资大于5K的员工总数 selectCOUNT(*)astotalfromT_Employee whereFSalary>5000 ------------------------------ -----数据排序------- ------------------------------ --按年龄排序升序,默认是升序 select*fromT_Employee orderbyFAgeASC --多个条件排序,先什么,后什么,在前一个条件相同的情况下,根据后一个条件进行排列 --where在orderby之前 select*fromT_Employee orderbyFAgeASC,FSalaryDESC ------------------------------ -----模糊匹配------- ------------------------------ --通配符查询 --1.单字符通配符_ --2.多字符通配符% --以DEV开头的任意个字符串 select*fromT_Employee whereFNumberlike'DEV%' --以一个字符开头,om结尾的字符串 select*fromT_Employee whereFNamelike'_om' --检索姓名中包含m的字符 select*fromT_Employee whereFNamelike'%m%' ------------------------------ -----空值处理------- ------------------------------ --null表示不知道,不是没有值 --null和其他值计算结果是null selectnull+1 --查询名字是null的数据 select*fromT_Employee whereFNameisnull --查询名字不为空null的数据 select*fromT_Employee whereFNameisnotnull --年龄是23,25,28中的员工 select*fromT_Employee whereFAge=23orFAge=25orFAge=28 --或者用in集合查询 --年龄是23,25,28中的员工 select*fromT_Employee whereFAgein(23,25,28) --年龄在20到25之间的员工信息 select*fromT_Employee whereFAge>20andFAge<25 --年龄在20到25之间的员工信息,包含25 select*fromT_Employee whereFAgebetween20and25 ------------------------------ -----数据分组------- ------------------------------ SelectFAge,COUNT(*)fromT_Employee groupbyFAge --1.根据年龄进行分组 --2.再取出分组后的年龄的个数 --注意:没有出现在groupby子句中的字段,不能出现在select语句后的列名列表中(聚合函数除外) --groupby必须出现在where后面 SelectFAge,AVG(FSalary),COUNT(*)fromT_Employee groupbyFAge --错误用法 SelectFAge,FName,COUNT(*)fromT_Employee groupbyFAge --加上where的groupby子句 --groupby必须出现在where后面 SelectFAge,AVG(FSalary),COUNT(*)fromT_Employee whereFAge>=25 groupbyFAge --Having不能包含查不到的字段,只能包含聚合函数和本次查询有关的字段 selectFAge,COUNT(*)fromT_Employee groupbyFAge HavingCOUNT(*)>1 selectFAge,COUNT(*)fromT_Employee whereFSalary>2500 groupbyFAge --HAVING子句中的列'T_Employee.FSalary'无效,因为该列没有包含在聚合函数或GROUPBY子句中 --Having是对分组后信息的过滤,能用的列和select中能有的列是一样的。 --因此,having不能代替where selectFAge,COUNT(*)fromT_Employee groupbyFAge HavingFSalary>2500 ------------------------------ -----确定结果集行数------- ------------------------------ --取出所有员工的信息,根据工资降序排列 select*fromT_Employee orderbyFSalaryDESC --取出前三名员工的信息,根据工资降序排列 selecttop3*fromT_Employee orderbyFSalaryDESC --根据工资取出排名在6-8的员工信息,按工资降排列 selecttop3*fromT_Employee whereFNumbernotin (selecttop5FNumberfromT_EmployeeorderbyFSalaryDESC) orderbyFSalaryDESC ---修改数据表,添加字段,更新字段的值等操作。 altertableT_EmployeeaddFSubCompanyvarchar(20) altertableT_EmployeeaddFDepartmentvarchar(20) updateT_EmployeesetFSubCompany='Beijing',FDepartment='Development' whereFNumber='DEV001'; updateT_EmployeesetFSubCompany='ShenZhen',FDepartment='Development' whereFNumber='DEV002'; updateT_EmployeesetFSubCompany='Beijing',FDepartment='HumanResource' whereFNumber='HR001'; updateT_EmployeesetFSubCompany='Beijing',FDepartment='HumanResource' whereFNumber='HR002'; updateT_EmployeesetFSubCompany='Beijing',FDepartment='InfoTech' whereFNumber='IT001'; updateT_EmployeesetFSubCompany='ShenZhen',FDepartment='InfoTech' whereFNumber='IT002' updateT_EmployeesetFSubCompany='Beijing',FDepartment='Sales' whereFNumber='SALES001'; updateT_EmployeesetFSubCompany='Beijing',FDepartment='Sales' whereFNumber='SALES002'; updateT_EmployeesetFSubCompany='ShenZhen',FDepartment='Sales' whereFNumber='SALES003'; select*fromT_Employee ------------------------------ ------去掉重复数据------ ------------------------------ --所有员工的部门信息 selectDistinctFDepartmentfromT_Employee; selectFDepartment,FSubCompany fromT_Employee --以上两个例子结合起来比较,Distinct针对的是整行进行比较的 selectDistinctFDepartment,FSubCompany fromT_Employee ----------------------------- -----联合结果集Union-------- ------------------------------ --创建一个测试表T_TempEmployee,并插入数据 CreateTableT_TempEmployee(FIdCardNumbervarchar(20),FNamevarchar(20),FAgeint,Primarykey(FIdCardNumber)); insertintoT_TempEmployee(FIdCardNumber,FName,FAge)values('1234567890121','Sarani',33); insertintoT_TempEmployee(FIdCardNumber,FName,FAge)values('1234567890122','Tom',26); insertintoT_TempEmployee(FIdCardNumber,FName,FAge)values('1234567890123','Yamaha',38); insertintoT_TempEmployee(FIdCardNumber,FName,FAge)values('1234567890124','Tina',36); insertintoT_TempEmployee(FIdCardNumber,FName,FAge)values('1234567890125','Konkaya',29); insertintoT_TempEmployee(FIdCardNumber,FName,FAge)values('1234567890126','Foortia',29); select*fromT_TempEmployee --Union关键字,联合2个结果 --把2个查询结果结合为1个查询结果 --要求:上下2个查询语句的字段(个数,名字,类型相容)必须一致 selectFName,FagefromT_TempEmployee union selectFName,FagefromT_Employee selectFNumber,FName,Fage,FDepartmentfromT_Employee union selectFIdCardNumber,FName,Fage,'临时工,无部门'fromT_TempEmployee ---UnionAll:不合并重复数据 --Union:合并重复数据 selectFName,FAgefromT_Employee unionall selectFName,FAgefromT_TempEmployee selectFAgefromT_Employee union selectFAgefromT_TempEmployee --注意:Union因为要进行重复值扫描,所以效率低,因此假如不是确定要合并重复,那么就用Unionall --例子:报名 select'正式员工最高年龄',MAX(FAge)fromT_Employee unionall select'正式员工最低年龄',MIN(FAge)fromT_Employee unionall select'临时工最高年龄',MAX(FAge)fromT_TempEmployee unionall select'临时工最低年龄',MIN(FAge)fromT_TempEmployee --查询每位正式员工的信息,包括工号,工资,并且在最后一行加上员工工资额合计 selectFNumber,FSalaryfromT_Employee unionall select'工资额合计',SUM(FSalary)fromT_Employee
------------------------------ -----SQL其他内置函数------ ------------------------------ --1.数学函数 --ABS():求绝对值 --CEILING():舍入到最大整数 --FLOOR():舍入到最小整数 --ROUND():四舍五入 selectABS(-3) selectCEILING(3.33) selectCEILING(-3.61) selectFLOOR(2.98) selectFLOOR(-3.61) selectROUND(-3.61,1)--第二个参数是精度,小数点后的位数 selectROUND(-3.61,0) selectROUND(3.1415926,3) --2.字符串函数 --LEN():计算字符串长度 --LOWER(),UPPER():转大小写 --LTRIM():去掉字符串左侧的空格 --RTRIM():去掉字符串右侧的空格 --SUBSTRING(string,start_positoin,length): --索引从1开始 selectSUBSTRING('abc111',2,3)--结果是bc1 selectFName,SUBSTRING(FName,2,2)fromT_Employee selectLEN('abc')--结果是3 selectFName,LEN(FName)fromT_Employee --没有可以同时既去掉左边空格、又去掉右边空格的TRIM()内置函数,所以先左后右的进行TRim,当然,你也可以先右后左 selectLTRIM('abc'),RTRIM('abc'),LEN(LTRIM(RTRIM('abc'))) --3.日期函数 --GETDATE():获取当前日期时间 --DATEADD(datepart,numbre,date):计算增加以后的日期, --参数date为待计算的日期;参数number为增量;参数datepart为计量单位,时间间隔单位; --DATEDIFF(datepart,startdate,enddate):计算2个日期之间的差额 --DATEPART(datepart,date):返回一个日期的特定部分,比如年月日,时分秒等. /* 值缩写(SqlServer)(Access和ASP)说明 YearYyyyyy年1753~9999 QuarterQqq季1~4 MonthMmm月1~12 DayofyearDyy一年的日数,一年中的第几日1-366 DayDdd日,1-31 WeekdayDww一周的日数,一周中的第几日1-7 WeekWkww周,一年中的第几周0~51 HourHhh时0~23 MinuteMin分钟0~59 SecondSss秒0~59 MillisecondMs-毫秒0~999 */ selectDATEADD(DAY,3,getdate()) selectDATEADD(MONTH,-3,getdate()) selectDATEADD(HOUR,8,getdate()) selectDATEDIFF(YEAR,'1989-05-01',GETDATE()) selectDATEDIFF(HH,GETDATE(),DATEADD(DAY,-3,GETDATE())) --查询员工的工龄,年为单位 selectFName,FInDate,DATEDIFF(year,FInDate,getdate())as工龄fromT_Employee --取出每一年入职员工的个数V1 selectDATEDIFF(year,FInDate,getdate()),COUNT(*) fromT_Employee groupbyDATEDIFF(year,FInDate,getdate()) --取出每一年入职员工的个数V2 selectDATEPART(YEAR,FInDate),COUNT(*) fromT_Employee groupbyDATEPART(YEAR,FInDate) selectDATEPART(YEAR,GETDATE()) selectDATEPART(MONTH,GETDATE()) selectDATEPART(DAY,GETDATE()) selectDATEPART(HH,GETDATE()) selectDATEPART(MINUTE,GETDATE()) selectDATEPART(SECOND,GETDATE()) --4.类型转换函数 --CAST(expressionasdata_type) --CONVERT(data_type,expression) selectCAST('123'asint),CAST('2010-09-08'asdatetime), CONVERT(datetime,'2010-09-08'),CONVERT(varchar(20),123) --5.空值处理函数isNull --ISNULL(expression,value) selectISNULL(FName,'佚名')as姓名fromT_Employee --6.CASE函数用法: --1.单值判断:相当于switch.case --CASEexpression --WHENvalue1thenreturnvalue1 --WHENvalue2thenreturnvalue2 --WHENvalue3thenreturnvalue3 --ELSEdefault_return_value --END --判断客户类型 selectFName, ( caseFLevel when1then'普通客户' when2then'会员' when3then'VIP' else'未知客户类型' End )as客户类型 fromT_Customer --收入水平查询 selectFName, ( case whenFSalary<2000then'低收入' whenFSalary>=2000andFSalary<=5000then'中等收入' else'高收入' end )as收入水平 fromT_Employee --这里有一道关于CASE用法的面试题 --表T中有ABC三列,用SQL语句实现:当A列大于B列时选择A列,否则选择B列; --当B列大于C列时选择B列,否则选择C列。 select ( case whena>bthenaelseb end ), ( case whenb>cthenbelsec end ) fromT --------------------------------------- selectFNumber, ( case whenFAmount>0thenFAmount else0 end )as收入, ( case whenFAmount<0thenABS(FAmount) else0 end )as支出 fromT ----------------------------------------- 二、SQL Server 中的数据类型
三、SQL中的内置函数