SQL Server数据库培训——Select语句构成元素

上一篇 / 下一篇  2011-03-31 14:27:25 / 个人分类:数据库

1.            Select语句构成元素

1.1         Select *

避免使用select *51Testing软件测试网%ENe6N7fc Krc&p a

当你想在SELECT子句中列出所有的COLUMN,使用动态SQL列引用*是一个方便的方法.不幸的是,这是一个非常低效的方法.实际上,SQL在解析的过程中,会将’*依次转换成所有的列名,这个工作是通过查询数据字典完成的,这意味着将耗费更多的时间.51Testing软件测试网\#va Qq8f"H

1.2         Select语句中元素的执行顺序

为了描述逻辑查询处理和各种SELECT查询子句,我们使用以下事例为大家介绍。

N_2WBvse0

例:查询出加拿大市场的所有绑定1个以上手机的用户,并且按用户ID排序。51Testing软件测试网a,NEv3\6mSK R

select ACCTID,count(*) numPhones

si j+mq@4z ]\0

from IFD_PHONE_LIST51Testing软件测试网4O1p/qqX0Hb3E-A

where NATION_CODE='CA'51Testing软件测试网X7R4og1ZK*Wp

group by ACCTID

z}5| AV)MV0

having count(*) >1

&?@ L&f8s"Ph9]FLD0

order by ACCTID51Testing软件测试网^8[&J,D~H

执行顺序如下:51Testing软件测试网.@2SF_G C

1.      FROM           

+dCk#ac@0

2.      WHERE          

5J"B!p0N2Tj R;cH.E0

3.      GTOUP BY      51Testing软件测试网;kN]Cvj4O'H

4.      HAVING51Testing软件测试网1J R7D.NQ2N

5.      SELECT

1Xf Q'\jd0

6.      ORDER BY51Testing软件测试网O1T;i%I%Y7@bH

这条查询语句会完成以下功能51Testing软件测试网Z6kI-]0w\

1.      IFD_PHONE_LIST表中查询数据行51Testing软件测试网s/X S4~/n$p

2.      对表中数据进行过滤,只保留市场为CA的记录51Testing软件测试网"uz `Mo^!\E0ZD'N:|

3.      按照用户ID对数据进行分组51Testing软件测试网/C+f2go @,K]

4.      对分组后的数据进行过滤,只保留绑定多个手机的用户51Testing软件测试网3M2q-bEK

5.      返回每个分组用户ID和手机数目

;b2PHGJ2I0

6.      按照用户ID对输出结果进行排序51Testing软件测试网,Z.? fuP+Z7m+?

所以如果sql改为

dM(f,j6YK@!\L6d0

select ACCTID,count(*) numPhones51Testing软件测试网 @v({5] K l

from IFD_PHONE_LIST

,N'ME[X}B*k)Y]0

where NATION_CODE='CA'andnumPhones>151Testing软件测试网3RF|kF

group by ACCTID

%F SWo*I.lh(NGWx0

having count(*) >151Testing软件测试网-p)|.]+?7o

order by ACCTID51Testing软件测试网lQc?'b&p

那么该sql会报错,因为这时字段还没有起别名,该操作是在where语句执行后才会执行。

*YF"f8J"T G0`7ur0

1.3         DISTINCT

SELECT指令可以查出我们想要的所有数据,但是在这些数据中可能有很多重复的值。

7|D4d5v So0

当需要查询某个表格中有哪些不同的值,而每个值出现的次数并不重要,那么这时就可以使用DISTINCT

#nD8cja$M8L0

使用方法51Testing软件测试网 imMFY V4mA

SELECT DISTINCT 字段名 FROM “表格名

fT}?M0

1.4         GROUP BY

Group by阶段可以将前面逻辑查询处理阶段返回的行按“组”进行组合。51Testing软件测试网)s0rcH,Z+Z;w

例:查询某个用户的近6月账单51Testing软件测试网{4Y+Pw1l3Upstb

select CYCLE_START as CycleStart,51Testing软件测试网xIy~4Euihq}H7L

               CYCLE_END as CycleEnd,51Testing软件测试网:p0zb8?~,L

               sum(TOLL_CHARGE) as TollCharge,51Testing软件测试网X ?.eAus

               sum(Credit) as Credit,

L8uu BN%K0

               sum(Debit) as Debit,

0pQ_1|"NM])Q8a0

               min(Due_Date) as DueDate51Testing软件测试网.x,z_O5Z#b

               from CYCLE_CALL_FEE_HISTORY

?^-o/q6EF0

               where acctid = 39129 and cycle_start>='2010-1-1' and cycle_end<='2010-6-1'51Testing软件测试网1ZYia5o8F@S7]

           group by CYCLE_START, CYCLE_END

$o:y e{%S!VZ@]:D0

因为聚合函数只为每个组返回一个值,所以一个元素如果不在group by里表中出现,就只能作为聚合函数(COUNT,SUM,AVG,MIN,MAX)的输入。但是所有的聚合函数都会忽略NULL值,只有一个例外COUNT*)。例如某列的值为3010NULL10.COUNT*)会返回4,而COUNT(列名)将返回3.51Testing软件测试网/I[C2H(U

1.5         ORDER BY

在一个表中的数据不一定是排序存放的。所以到需要排序时51Testing软件测试网Q j ~2GK`]0nf

ORDER BY语句用于根据指定的列对结果集进行排序。51Testing软件测试网hF,Lu{%]!b

ORDER BY语句默认按照升序对记录进行排序。51Testing软件测试网:Y'{mK"d2k

如果您希望按照降序对记录进行排序,可以使用DESC关键字。51Testing软件测试网/W"}jVk g0t

1.6         IS NULL

当要查询一个字段为null的记录时,要使用is null而不是!= nul51Testing软件测试网Y@(Xu#NOA6U _

1.7         NOT

NOT运算符用于对搜索条件的布尔值求反。这里讨论NOT运算符的使用、应用场合及其与<>运算符的区别。

5p9d%k4}4~ E2l#?@0

其他运算符不同,表示否定的NOT运算符不能单独应用,而经常与其他运算符联合使用。例如,NOT IN运算符实际上就是IN运算符与NOT运算符的联合使用51Testing软件测试网+? z&sXA MC"JP

:使用NOT运算符实现查询

B;Wlr@ ^v0

SELECT TNAME, DNAME,AGE, TSEX FROM TEACHER  WHERE NOT DNAME='计算机' ORDER BY DNAME

e E}8K [HVy3VZ0

NOT运算符对紧跟其后的条件取反,NOT DNAME=‘计算机’实际上就等价于DNAME<>‘计算机’或者DNAME!=‘计算机’。51Testing软件测试网J^ k8I7B

需要强调一点,NULL值进行取反,结果仍是NULL.

2z V"N0{7pA0

NULL值的取反

wkb9J Z&zG6rR0

如下面的代码:51Testing软件测试网B^ f/Ui9| MYQ

SELECT * FROM TEACHER WHERE NOT SAL >1500 OREDR BY SAL

X5K"jHbz0

上述实例代码实际上是查询所有工资不高于1500的教师信息,从结果中发现,工资为NULL的教师记录并没有包括在结果表中。因为当SALNULL时,“SAL >1500”的执行结果也为NULL,而NOT NULL的运算结果仍然为NULL,也就不满足查询条件。

.Iy gO'o lT+Fnr0

1.8         Between And

使用BETWEEN...AND操作符可以选中排列于两值之间的数据。这些数据可以是数字,文字或是日期。在SQL使用相当于>=<=51Testing软件测试网 H0Y_&lM pZB

1.9         Top

例:查询出前10掉记录51Testing软件测试网&b\mBP3C.R9h~

select top 10 account_id,plan_id,status

$A&H'EO6O0

from account_extension51Testing软件测试网&TX/Pe0~2h2~&\

order by account_id51Testing软件测试网|n(E B Y;~9]

这里要注意执行顺序,查询出的数据会先进行排序再查出前10行记录51Testing软件测试网p0E f j0`\(s!Eu)u

 

;z3hJ,b\*XM`0

SQL Server 2005之前的传统SQL语句中,top语句是不支持局部变量的。此时可以使用Set RowCount,但是在SQL Server 2005/2008中,TOP通常执行得更快,所以应该用TOP关键字来取代Set RowCount

0u?F VL8`,v0

Declare @percentage floatset

?'w9|1Pd3?"r;p0

@percentage=151Testing软件测试网3hQ1uOUs

select Top (@percentage) percent PName from [Demo_Top] order by PName

(q'v2J&c rz0

例:利用toppercent分页

9][-D)T @0

查出前1%的数据51Testing软件测试网~z"P^l.qh(pf c

select Top 1 percent OrderID from Orders order by OrderID51Testing软件测试网-b\C9q^3La)O

查出前2%的数据51Testing软件测试网w5\!y0S5wA d;I

select Top 2 percent * from Orders where OrderID not in

6YR)V Ahj%ic0

( select Top 1 percent OrderID from Orders order by OrderID) order by OrderID51Testing软件测试网"j/]1Q"^3\B ~

1.10     Table Partition

数据库结构和索引的是否合理在很大程度上影响了数据库的性能,但是随着数据库信息负载的增大,对数据库的性能也发生了很大的影响。可能我们的数据库在一开始有着很高的性能,但是随着数据存储量的急速增长—例如通话记录数据—数据的性能也受到了极大的影响,一个很明显的结果就是查询的反应会非常慢。在这个时候,除了你可以优化索引及查询外,你还可以建立分区表(Table Partition),在某些场合下提高数据库的性能,在SQL Server 2008中提供了向导形式来创建分区表。

7X!U3E4o[Ux1Z.T/V0

例:在fact_sales表中针对date_id以月为单位做分区后执行以下语句。51Testing软件测试网9k2I9QX7? R^}

SELECT date_id, SUM(quantity*unit_price) AS total_price

(m Zk.x oS y(`J0

FROM fact_sales51Testing软件测试网Z`{e4Y%Q

WHERE date_id BETWEEN 20080801 AND 2008083151Testing软件测试网x(|8CA/P}w

这时对date_id进行查询时,会从指定分区表内提取数据从而可以提高查询效率

TKT$p$R0

1.11     OVER

确定在应用关联的开窗函数之前,行集的分区和排序51Testing软件测试网 fH3Gy\.G*k@B

PARTITION BY参数51Testing软件测试网.VN5C J9i,h[~

将结果集分为多个分区。开窗函数分别应用于每个分区,并为每个分区重新启动计算。

W+m1C \pqY)d0

例:

W5JfQGBO j0

select orderid,custid,val,51Testing软件测试网*Z+@w(@K'N

   sum(val) over() as totalvalue,51Testing软件测试网5X8j0Ns*W

   sum(val) over(partition by custid) as custtotalval51Testing软件测试网QTK1L3i@*x%S-HG

from ordervalues51Testing软件测试网@a p#dUi k1PDD/xbY

 51Testing软件测试网n]!n q,I"yB$V0e0j

Over使用PARTITION BY,并且按照特定字段排序

2g;fJ:ArZ N\0

251Testing软件测试网 J"Hm2i.I z

select orderid,custid,val,

L9faJ,t `$p0

   row_number() over(partition by custid

k7i|J0|_|7tw0

                   order by val) as rownum

'E kM}\h0

from ordervalues51Testing软件测试网#@-MSxV#s.P

order by custid,val

N,ET&l1~\*U"}0

 51Testing软件测试网$Zq yYcBy


TAG:

 

评分:0

我来说两句

Open Toolbar