当前位置:首页 » 编程语言 » 复杂sql语句分析
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

复杂sql语句分析

发布时间: 2022-08-18 03:12:08

Ⅰ 比较复杂的sql语句

如果你的是ACCESS数据库或者MS SQL数据库,可以使用视图来实现,做起来很容易的。你可以试一下。
以下介绍主要方法:
INNER JOIN 运算
组合两个表中的记录,只要在公共字段之中有相符的值。

语法
FROM table1 INNER JOIN table2 ON table1.field1 compopr table2.field2

INNER JOIN 运算可分为以下几个部分:

部分 说明
table1, table2 记录被组合的表的名称。
field1, field2 被联接的字段的名称。若它们不是由数字构成的,则这些字段必须为相同的数据类型并包含同类数据,但它们无须具有相同的名称。
compopr 任何的关系比较运算子:"=," "<," ">," "<=," ">=," 或 "<>."

说明
可以在 FROM 子句中使用INNER JOIN运算。.这是最普通的联接类型。只要在这两个表的公共字段之中有相符值,内部联接将组合两个表中的记录。

可以使用 INNER JOIN 与部门表及员工表选择每一个部门中的全部员工。反之,可以使用 LEFT JOIN或 RIGHT JOIN运算创建 outer join,从而选择所有部门(即使有些并没有员工)或所有员工(即使有些尚未分配到部门)。

若试图联接包含 Memo或 OLE Object数据的字段,会导致错误。

可以联接任何两个相同类型的数值字段。例如,可以联接 AutoNumber和 Long字段,因为它们类型相似。但不能联接 Single 和 Double 类型的字段。

下列示例显示如何在类标识符字段联接类表及产品表:

SELECT CategoryName, ProctName

FROM Categories INNER JOIN Procts

ON Categories.CategoryID = Procts.CategoryID;

在上面的示例中,类标识符是已被联接的字段,但是它并不包含在查询输出中,因它并非被包含在 SELECT 语句之中。在这个示例中,若要包含联接字段,将字段名包含在 SELECT 语句中, Categories.CategoryID.

也可以使用下列语法,在一个 JOIN 语句中链接多个 ON 子句:

SELECT fields
FROM table1 INNER JOIN table2
ON table1.field1 compopr table2.field1 AND
ON table1.field2 compopr table2.field2) OR
ON table1.field3 compopr table2.field3)];

也可以使用下列语法,嵌套 JOIN 语句:

SELECT fields
FROM table1 INNER JOIN
(table2 INNER JOIN [( ]table3
[INNER JOIN [( ]tablex [INNER JOIN ...)]
ON table3.field3 compopr tablex.fieldx)]
ON table2.field2 compopr table3.field3)
ON table1.field1 compopr table2.field2;

在一个 INNER JOIN 之中,可以嵌套 LEFT JOIN 或 RIGHT JOIN,但是在 LEFT JOIN 或 RIGHT JOIN 中不能嵌套 INNER JOIN。

Ⅱ SQL语句分析—急~给加分

第一个两个表建立内连接条件是
第二个在表中查询出id=1到5的记录 ordery by 是按照后面的字段升序排列……

Ⅲ SQL语句求分析

UPDATE[Notifications]WITH(TABLOCKX)
SET[BatchID]=@BatchID,
[ProcessStart]=GETUTCDATE(),
[ProcessHeartbeat]=GETUTCDATE()
FROM(
SELECTTOP1[NotificationID]FROM[Notifications]WITH(TABLOCKX)WHEREProcessStartisNULLand
(<GETUTCDATE())ORDERBY[NotificationEntered]
)ASt1,[Notifications]a
WHEREa.[NotificationID]=t1.[NotificationID]

Ⅳ 一句复杂的SQL语句高手看看

select MCDJNBXH,QYMC,ZWZH,PYZH,QYLX,MCLB,DJJG,HZTZSWH,HZJG,MCBLQZ,HZRQ,'SL' as BM from SL_QYMCHZK where 1=1 AND MCLB in ('6','7','9','10','15') AND QYMC like "5566"
//这是第一句 连执行一下看看它的结果集 如果我们命名如果集为数组$r_1
select row_.*,rownum rownum_ from $r_1 row_ where rownum<=122
//这是第二句 分析$r_1之后再看看这句的结果集 定义为$r_2
Select * from $r_2 where rownum>101
//最后出最终的结果集 从sql语句看$r_1 $r_2是表名

Ⅳ 复杂的SQL语句该如何实现

declare @aa1 char(10)
declare @aa2 char(10)
declare @aa3 char(10)

set @aa1 = (select top 1 a from [table1])

set @aa2 = (select top 1 * from (select top 2 * from [table1] order by a asc) [table1] order by a desc)

set @aa3 = (select top 1 * from (select top 3 * from [table1] order by a asc) [table1] order by a desc)

insert [item1,item2,item3] values (@aa1,@aa2,@aa3)
/* 不能完美解决,待me参考资料 ^_^*/

Ⅵ 一段很复杂很复杂的SQL语句。。求大神解释。。。

Select
*
From
(
Select
*
From
(
Select
Number
,ChineseName
,tb1.DepartmentCode
,DepartmentName
,ShiftId
,ShiftName
,Degree
,AskForLeaveType
,WorkOnDate
,OnDutyType
,StartTime
,EndTime
,AOnDuty
,AOffDuty
,Allday
,tb1.SumTotal
,'Error'=
Case
WhenDegree=1ANDStartTime<=AOnDutyANDEndTime<=AOnDutyANDShiftId>0ANDLeft(AskForLeaveType,1)='0'Then0
WhenDegree=1ANDStartTime>=AOffDutyANDShiftId>0ANDLeft(AskForLeaveType,1)='0'Then0
WhenDegree=1ANDStartTime>=WorkOnDate+''+'12:30'ANDEndTime<=WorkOnDate+''+'13:30'ANDCharindex('常白班',ShiftName)>0ANDShiftId>0ANDLeft(AskForLeaveType,1)='0'Then0
WhenDegree=2ANDStartTime<=AOnDutyANDEndTime<=AOnDutyANDShiftId>0ANDLeft(AskForLeaveType,1)='0'Then0
WhenDegree=2ANDStartTime>=AOffDutyANDEndTime<=BOnDutyANDShiftId>0ANDLeft(AskForLeaveType,1)='0'Then0
WhenDegree=2ANDStartTime>=BOffDutyANDShiftId>0ANDLeft(AskForLeaveType,1)='0'Then0
WhenDegree=3ANDStartTime<=AOnDutyANDEndTime<=AOnDutyANDShiftId>0ANDLeft(AskForLeaveType,1)='0'Then0
WhenDegree=3ANDStartTime>=AOffDutyANDEndTime<=BOnDutyANDShiftId>0ANDLeft(AskForLeaveType,1)='0'Then0
WhenDegree=3ANDStartTime>=BOffDutyANDEndTime<=COnDutyANDShiftId>0ANDLeft(AskForLeaveType,1)='0'Then0
WhenDegree=3ANDStartTime>=COffDutyANDShiftId>0ANDLeft(AskForLeaveType,1)='0'Then0
WhenShiftId=0ANDLeft(AskForLeaveType,1)='0'Then0
WhenShiftId>0ANDLeft(AskForLeaveType,1)<>'0'ANDLeft(OnDutyType,1)=0Then0
WhenShiftId>0ANDLeft(AskForLeaveType,1)<>'0'ANDLeft(OnDutyType,1)=2ANDAskForLeaveType='出差假'Then0
WhenShiftId>0ANDLeft(AskForLeaveType,1)<>'0'ANDLeft(OnDutyType,1)=2ANDAskForLeaveType='产假'Then0
WhenShiftId=0ANDLeft(AskForLeaveType,1)<>'0'ANDConvert(varchar(10),StartTime,108)='00:00:00'ANDConvert(varchar(10),EndTime,108)='00:30:00'Then0
Else
1
End
From
(
Select
Number
,ChineseName
,DepartmentName
,d.DepartmentCode
,p.ShiftId
,p.ShiftName
,Degree
,AskForLeaveType
,Convert(varchar(10),WorkOnDate,120)as'WorkOnDate'
,StartTime
,EndTime
,AllDay
,SumTotal
,CaseWhenRight(Convert(Varchar(10),WorkOnDate,120),5)IN(selectRight(Convert(Varchar(10),HolidayDate,120),5)FromAttendanceHoliday)THEN'2-公众假上班'ELSE'0-平时上班'ENDAS'OnDutyType'
,CaseWhenLeft(FristBrushDate,1)='1'ANDConvert(varchar(10),AOffDuty,120)>Convert(varchar(10),AOnDuty,120)ThenCAST(Convert(Varchar(11),Dateadd(dd,-1,OnDutyDate),120)+Convert(Varchar(5),AOnDuty,108)ASDateTime)ELSECAST(Convert(Varchar(11),OnDutyDate,120)+Convert(Varchar(5),AOnDuty,108)ASDateTime)EndAS'AOnDuty'
,CaseWhenLeft(FristBrushDate,1)='0'ANDConvert(varchar(10),AOnDuty,120)<Convert(varchar(10),AOffDuty,120)ThenCAST(Convert(Varchar(11),Dateadd(dd,1,OnDutyDate),120)+Convert(Varchar(5),AOffDuty,108)ASDateTime)ELSECAST(Convert(Varchar(11),OnDutyDate,120)+Convert(Varchar(5),AOffDuty,108)ASDateTime)EndAS'AOffDuty'
,CAST(Convert(Varchar(11),OnDutyDate,120)+Convert(Varchar(5),BOnDuty,108)ASDateTime)AS'BOnDuty'
,CAST(Convert(Varchar(11),OnDutyDate,120)+Convert(Varchar(5),BOffDuty,108)ASDateTime)AS'BOffDuty'
,CAST(Convert(Varchar(11),OnDutyDate,120)+Convert(Varchar(5),COnDuty,108)ASDateTime)AS'COnDuty'
,CAST(Convert(Varchar(11),OnDutyDate,120)+Convert(Varchar(5),COffDuty,108)ASDateTime)AS'COffDuty'
From
.DepartmentCode=d.DepartmentCode
.Employeeid=a.Employeeid
INNERJOINAttendanceSpellpona.Employeeid=p.Employeeidanda.WorkOndate=p.OnDutyDate
LEFTJOINAttendanceShiftssonp.Shiftid=s.Shiftid
)tb1
)tb2WhereError=1

UNIONALL

Select
Number
,ChineseName
,DepartmentCode
,DepartmentName
,ShiftId
,ShiftName
,Degree
,AskForLeaveType
,WorkOnDate
,CaseWhenRight(Convert(Varchar(10),WorkOnDate,120),5)IN(selectRight(Convert(Varchar(10),HolidayDate,120),5)fromAttendanceHoliday)THEN'2-公众假上班'ELSE'0-平时上班'ENDAS'OnDutyType'
,StartTime
,EndTime
,AOnDuty
,AOffDuty
,Allday
,SumTotal
,Error
From
(
Select
Number
,ChineseName
,d.DepartmentCode
,DepartmentName
,p.ShiftId
,p.ShiftName
,Degree
,AskForLeaveType
,WorkOnDate
,StartTime
,EndTime
,Sumtotal
,NULLAS'AOnDuty'
,NULLAS'AOffDuty'
,AllDay
,1AS'Error'
From
AttendanceAskForLeavea
LEFTJOINEmployeeseONa.Employeeid=e.Employeeid
LEFTJOINDepartmentsdONe.DepartmentCode=d.DepartmentCode
LEFTJOINAttendanceSpellpONa.Employeeid=p.EmployeeidANDa.WorkOnDate=p.OnDutyDate
LEFTJOINAttendanceShiftssONp.ShiftId=s.ShiftId
Where
Left(IncumbencyStatus,1)<>1
Groupby
Number,ChineseName,d.DepartmentCode,DepartmentName,p.ShiftId,p.ShiftName,Degree,AskForLeaveType,AllDay,WorkOnDate,StartTime,EndTime,Sumtotal
having
Count(1)>1
)tb3
)tb4

对你的代码格式化后发现,还缺少一些语句,你是否粘贴完整了?

读完SQL语句后发现,其实是一个考勤核算的查询语句,是两个大的SQL查询Union ALL的结果

Ⅶ 复杂的sql语句

不是很复杂,只有一个子查询,最后那个from里边有很多内连接和外连接,主要是跟业务相关的,表多点不复杂,不知道你的业务逻辑,说不清楚
主要函数,
case when,就是根据不同的case选择一个结果
decode,跟case when差不多,DECODE(value, if1, then1, if2,then2, if3,then3, . . . else )
nvl,判断是否为空的,NVL( string1, replace_with) ,如果为空就用replace_with代替
group by rollup,不太容易说清楚,给你个连接自己看吧做个小例子也容易理解
http://blog.csdn.net/ghostgant/article/details/5699731

Ⅷ 复杂sql语句查询

selectid,name,isnull((selectSUM(金额)fromB表whereid=A表.idandbno=20),0)正常消费,isnull((selectSUM(金额)fromB表whereid=A表.idandbno=30),0)充值,(selecttop1余额fromB表whereid=A表.idorderby时间desc)余额,(selectMAX(时间)fromB表whereid=A表.id)时间
fromA表

这样看一下行不行

Ⅸ 如何对变异的sql语句做解析处理

优化SQL查询:如何写出高性能SQL语句1、首先要搞明白什么叫执行计划?执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生欀如一条SQL语句如果用来从一个10万条记录的表中查1条记录,那查询优化器会选择“索引查找”方式,如果该表进行了归档,当前只剩下5000条记录了,那查询优化器就会改变方案,采用“全表扫描”方式。可见,执行计划并不是固定的,它是“个性化的”。产生一个正确的“执行计划”有两点很重要:(1)SQL语句是否清晰地告诉查询优化器它想干什么?(2)查询优化器得到的数据库统计信息是否是最新的、正确的?2、统一SQL语句的写法对于以下两句SQL语句,程序员认为是相同的,数据库查询优化器认为是不同的。select*fromalselect*Fromal其实就是大小写不同,查询分析器就认为是两句不同的SQL语句,必须进行两次解析。生成2个执行计划。所以作为程序员,应该保证相同的查询语句在任何地方都一致,多一个空格都不行!3、不要把SQL语句写得太复杂我经常看到,从数据库中捕捉到的一条SQL语句打印出来有2张A4纸这么长。一般来说这么复杂的语句通常都是有问题的。我拿着这2页长的SQL语句去请教原作者,结果他说时间太长,他一时也看不懂了。可想而知,连原作者都有可能看糊涂的SQL语句,数据库也一样会看糊涂。一般,将一个Select语句的结果作为子集,然后从该子集中再进行查询,这种一层嵌套语句还是比较常见的,但是根据经验,超过3层嵌套,查询优化器就很容易给出错误的执行计划。因为它被绕晕了。像这种类似人工智能的东西,终究比人的分辨力要差些,如果人都看晕了,我可以保证数据库也会晕的。另外,执行计划是可以被重用的,越简单的SQL语句被重用的可能性越高。而复杂的SQL语句只要有一个字符发生变化就必须重新解析,然后再把这一大堆垃圾塞在内存里。可想而知,数据库的效率会何等低下。4、使用“临时表”暂存中间结果简化SQL语句的重要方法就是采用临时表暂存中间结果,但是,临时表的好处远远不止这些,将临时结果暂存在临时表,后面的查询就在tempdb中了,这可以避免程序中多次扫描主表,也大大减少了程序执行中“共享锁”阻塞“更新锁”,减少了阻塞,提高了并发性能。5、OLTP系统SQL语句必须采用绑定变量select*>’2010-10-2000:00:01′select*>’2010-09-2200:00:01′以上两句语句,查询优化器认为是不同的SQL语句,需要解析两次。如果采用绑定变量select*>@chgtime@chgtime变量可以传入任何值,这样大量的类似查询可以重用该执行计划了,这可以大大降低数据库解析SQL语句的负担。一次解析,多次重用,是提高数据库效率的原则。6、绑定变量窥测事物都存在两面性,绑定变量对大多数OLTP处理是适用的,但是也有例外。比如在where条件中的字段是“倾斜字段”的时候。“倾斜字段”指该列中的绝大多数的值都是相同的,一张人口调查表,其中“民族”这列,90%以上都是汉族。那么如果一个SQL语句要查询30岁的汉族人口有多少,那“民族”这列必然要被放在where条件中。这个时候如果采用绑定变量@nation会存在很大问题。试想如果@nation传入的第一个值是“汉族”,那整个执行计划必然会选择表扫描。然后,第二个值传入的是“布依族”,按理说“布依族”占的比例可能只有万分之一,应该采用索引查找。但是,由于重用了第一次解析的“汉族”的那个执行计划,那么第二次也将采用表扫描方式。这个问题就是着名的“绑定变量窥测”,建议对于“倾斜字段”不要采用绑定变量。7、只在必要的情况下才使用begintranSQLServer中一句SQL语句默认就是一个事务,在该语句执行完成后也是默认commit的。其实,这就是begintran的一个最小化的形式,好比在每句语句开头隐含了一个begintran,结束时隐含了一个commit。有些情况下,我们需要显式声明begintran,比如做“插、删、改”操作需要同时修改几个表,要求要么几个表都修改成功,要么都不成功。begintran可以起到这样的作用,它可以把若干SQL语句套在一起执行,最后再一起commit。好处是保证了数据的一致性,但任何事情都不是完美无缺的。Begintran付出的代价是在提交之前,所有SQL语句锁住的资源都不能释放,直到commit掉。可见,如果Begintran套住的SQL语句太多,那数据库的性能就糟糕了。在该大事务提交之前,必然会阻塞别的语句,造成block很多。Begintran使用的原则是,在保证数据一致性的前提下,begintran套住的SQL语句越少越好!有些情况下可以采用触发器同步数据,不一定要用begintran。8、一些SQL查询语句应加上nolock在SQL语句中加nolock是提高SQLServer并发性能的重要手段,在oracle中并不需要这样做,因为oracle的结构更为合理,有undo表空间保存“数据前影”,该数据如果在修改中还未commit,那么你读到的是它修改之前的副本,该副本放在undo表空间中。这样,oracle的读、写可以做到互不影响,这也是oracle广受称赞的地方。SQLServer的读、写是会相互阻塞的,为了提高并发性能,对于一些查询,可以加上nolock,这样读的时候可以允许写,但缺点是可能读到未提交的脏数据。使用nolock有3条原则。(1)查询的结果用于“插、删、改”的不能加nolock!(2)查询的表属于频繁发生页分裂的,慎用nolock!(3)使用临时表一样可以保存“数据前影”,起到类似oracle的undo表空间的功能,能采用临时表提高并发性能的,不要用nolock。9、聚集索引没有建在表的顺序字段上,该表容易发生页分裂比如订单表,有订单编号orderid,也有客户编号contactid,那么聚集索引应该加在哪个字段上呢?对于该表,订单编号是顺序添加的,如果在orderid上加聚集索引,新增的行都是添加在末尾,这样不容易经常产生页分裂。然而,由于大多数查询都是根据客户编号来查的,因此,将聚集索引加在contactid上才有意义。而contactid对于订单表而言,并非顺序字段。比如“张三”的“contactid”是001,那么“张三”的订单信息必须都放在这张表的第一个数据页上,如果今天“张三”新下了一个订单,那该订单信息不能放在表的最后一页,而是第一页!如果第一页放满了呢?很抱歉,该表所有数据都要往后移动为这条记录腾地方。SQLServer的索引和Oracle的索引是不同的,SQLServer的聚集索引实际上是对表按照聚集索引字段的顺序进行了排序,相当于oracle的索引组织表。SQLServer的聚集索引就是表本身的一种组织形式,所以它的效率是非常高的。也正因为此,插入一条记录,它的位置不是随便放的,而是要按照顺序放在该放的数据页,如果那个数据页没有空间了,就引起了页分裂。所以很显然,聚集索引没有建在表的顺序字段上,该表容易发生页分裂。曾经碰到过一个情况,一位哥们的某张表重建索引后,插入的效率大幅下降了。估计情况大概是这样的。该表的聚集索引可能没有建在表的顺序字段上,该表经常被归档,所以该表的数据是以一种稀疏状态存在的。比如张三下过20张订单,而最近3个月的订单只有5张,归档策略是保留3个月数据,那么张三过去的15张订单已经被归档,留下15个空位,可以在insert发生时重新被利用。在这种情况下由于有空位可以利用,就不会发生页分裂。但是查询性能会比较低,因为查询时必须扫描那些没有数据的空位。重建聚集索引后情况改变了,因为重建聚集索引就是把表中的数据重新排列一遍,原来的空位没有了,而页的填充率又很高,插入数据经常要发生页分裂,所以性能大幅下降。对于聚集索引没有建在顺序字段上的表,是否要给与比较低的页填充率?是否要避免重建聚集索引?是一个值得考虑的问题!10、加nolock后查询经常发生页分裂的表,容易产生跳读或重复读加nolock后可以在“插、删、改”的同时进行查询,但是由于同时发生“插、删、改”,在某些情况下,一旦该数据页满了,那么页分裂不可避免,而此时nolock的查询正在发生,比如在第100页已经读过的记录,可能会因为页分裂而分到第101页,这有可能使得nolock查询在读101页时重复读到该条数据,产生“重复读”。同理,如果在100页上的数据还没被读到就分到99页去了,那nolock查询有可能会漏过该记录,产生“跳读”。上面提到的哥们,在加了nolock后一些操作出现报错,估计有可能因为nolock查询产生了重复读,2条相同的记录去插入别的表,当然会发生主键冲突。11、使用like进行模糊查询时应注意有的时候会需要进行一些模糊查询比如select*fromcontactwhereusernamelike‘%yue%’关键词%yue%,由于yue前面用到了“%”,因此该查询必然走全表扫描,除非必要,否则不要在关键词前加%,12、数据类型的隐式转换对查询效率的影响sqlserver2000的数据库一的程序在提交sql语句的时候,没有使用强类型提交这个字段的值,由sqlserver2000自动转换数据类型,会导致传入的参数与主键字段类型不一致,这个时候sqlserver2000可能就会使用全表扫描。Sql2005上没有发现这种问题,但是还是应该注意一下。13、SQLServer表连接的三种方式(1)MergeJoin(2)NestedLoopJoin(3)HashJoinSQLServer2000只有一种join方式——NestedLoopJoin,如果A结果集较小,那就默认作为外表,A中每条记录都要去B中扫描一遍,实际扫过的行数相当于A结果集行数xB结果集行数。所以如果两个结果集都很大,那Join的结果很糟糕。SQLServer2005新增了MergeJoin,如果A表和B表的连接字段正好是聚集索引所在字段,那么表的顺序已经排好,只要两边拼上去就行了,这种join的开销相当于A表的结果集行数加上B表的结果集行数,一个是加,一个是乘,可见mergejoin的效果要比NestedLoopJoin好多了。如果连接的字段上没有索引,那SQL2000的效率是相当低的,而SQL2005提供了Hashjoin,相当于临时给A,B表的结果集加上索引,因此SQL2005的效率比SQL2000有很大提高,我认为,这是一个重要的原因。总结一下,在表连接时要注意以下几点:(1)连接字段尽量选择聚集索引所在的字段(2)仔细考虑where条件,尽量减小A、B表的结果集(3)如果很多join的连接字段都缺少索引,而你还在用SQLServer2000,赶紧升级吧。

Ⅹ 一个asp中的复杂sql语句

这句SQL 是在具体的软件编程中使用的
这句SQL语句是在lyb表中添加 (姓名,email,主题,内容) 这些字段的值
在 values 后面就是对这些字段所加入的值。
你所学的SQL语句在查询分析器中是要写成 insert into lyb(姓名,email,主题,内容) values('jay','[email protected]','主题','内容')
可是在具体使用中 values 后面的那些值就需要从输入页面上来 在你不确定那些输入的值将是什么 那就需要用一个变量来存 而这些变量就是 NAME ,Email,Subject,Memo
以这个语句来说 NAME = "jay"; EMAIL="[email protected]" 等等
在SQL语句中 用单引号'' 把变量给引用出来 而在编程中你需要引用外部变量就要用 双引号“” 框起来;至于为什么要用加+ 是为了把字符串连接起来