﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-少年阿宾-随笔分类-Database</title><link>http://www.blogjava.net/stevenjohn/category/51105.html</link><description>那些青春的岁月</description><language>zh-cn</language><lastBuildDate>Wed, 14 Oct 2015 01:24:24 GMT</lastBuildDate><pubDate>Wed, 14 Oct 2015 01:24:24 GMT</pubDate><ttl>60</ttl><item><title>mysql oracle</title><link>http://www.blogjava.net/stevenjohn/archive/2015/10/11/427690.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Sun, 11 Oct 2015 14:05:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2015/10/11/427690.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/427690.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2015/10/11/427690.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/427690.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/427690.html</trackback:ping><description><![CDATA[mysql中&nbsp;myisam&nbsp;引擎不支持事务的概念，多用于数据仓库这样查询多而事务少的情况，速度较快。<br />mysql中&nbsp;innoDB&nbsp;引擎支持事务的概念，多用于web网站后台等实时的中小型事务处理后台。<br /><br />而oracle没有引擎的概念，oracle有OLTP和OLAP模式的区分，两者的差别不大，只有参数设置上的不同。<br />oracle无论哪种模式都是支持事务概念的，oracle是一个不允许读脏的数据库系统。<br /><br /><br /><br /><span style="color: #454545; font-family: arial, 宋体, sans-serif, tahoma, 'Microsoft YaHei'; line-height: 24px; background-color: #ffffff;">当今的数据处理大致可以分成两大类：联机事务处理OLTP（on-line transaction processing）、联机分析处理OLAP（On-Line Analytical Processing）。OLTP是传统的关系型数据库的主要应用，主要是基本的、日常的事务处理，例如银行交易。OLAP是数据仓库系统的主要应用，支持复杂的分析操作，侧重决策支持，并且提供直观易懂的查询结果.</span><br style="color: #454545; font-family: arial, 宋体, sans-serif, tahoma, 'Microsoft YaHei'; line-height: 24px; background-color: #ffffff;" /><span style="color: #454545; font-family: arial, 宋体, sans-serif, tahoma, 'Microsoft YaHei'; line-height: 24px; background-color: #ffffff;">OLTP:</span><br style="color: #454545; font-family: arial, 宋体, sans-serif, tahoma, 'Microsoft YaHei'; line-height: 24px; background-color: #ffffff;" /><span style="color: #454545; font-family: arial, 宋体, sans-serif, tahoma, 'Microsoft YaHei'; line-height: 24px; background-color: #ffffff;">也称为面向交易的处理系统，其基本特征是顾客的原始数据可以立即传送到计算中心进行处理，并在很短的时间内给出处理结果。</span><br style="color: #454545; font-family: arial, 宋体, sans-serif, tahoma, 'Microsoft YaHei'; line-height: 24px; background-color: #ffffff;" /><span style="color: #454545; font-family: arial, 宋体, sans-serif, tahoma, 'Microsoft YaHei'; line-height: 24px; background-color: #ffffff;">这样做的最大优点是可以即时地处理输入的数据，及时地回答。也称为实时系统(Real time System)。衡量联机事务处理系统的一个重要性能指标是系统性能，具体体现为实时响应时间(Response Time)，即用户在终端上送入数据之后，到计算机对这个请求给出答复所需要的时间。OLTP是由数据库引擎负责完成的。</span><br style="color: #454545; font-family: arial, 宋体, sans-serif, tahoma, 'Microsoft YaHei'; line-height: 24px; background-color: #ffffff;" /><span style="color: #454545; font-family: arial, 宋体, sans-serif, tahoma, 'Microsoft YaHei'; line-height: 24px; background-color: #ffffff;">OLTP 数据库旨在使事务应用程序仅写入所需的数据，以便尽快处理单个事务。</span><br style="color: #454545; font-family: arial, 宋体, sans-serif, tahoma, 'Microsoft YaHei'; line-height: 24px; background-color: #ffffff;" /><span style="color: #454545; font-family: arial, 宋体, sans-serif, tahoma, 'Microsoft YaHei'; line-height: 24px; background-color: #ffffff;">OLAP:</span><br style="color: #454545; font-family: arial, 宋体, sans-serif, tahoma, 'Microsoft YaHei'; line-height: 24px; background-color: #ffffff;" /><span style="color: #454545; font-family: arial, 宋体, sans-serif, tahoma, 'Microsoft YaHei'; line-height: 24px; background-color: #ffffff;">简写为OLAP,随着数据库技术的发展和应用，数据库存储的数据量从20世纪80年代的兆（M）字节及千兆（G）字节过渡到现在的兆兆（T）字节和千兆兆（P）字节，同时，用户的查询需求也越来越复杂，涉及的已不仅是查询或操纵一张关系表中的一条或几条记录，而且要对多张表中千万条记录的数据进行数据分析和信息综合，关系数据库系统已不能全部满足这一要求。在国外，不少软件厂商采取了发展其前端产品来弥补关系数据库管理系统支持的不足，力图统一分散的公共应用逻辑，在短时间内响应非数据处理专业人员的复杂查询要求。</span><br style="color: #454545; font-family: arial, 宋体, sans-serif, tahoma, 'Microsoft YaHei'; line-height: 24px; background-color: #ffffff;" /><span style="color: #454545; font-family: arial, 宋体, sans-serif, tahoma, 'Microsoft YaHei'; line-height: 24px; background-color: #ffffff;">联机分析处理（OLAP）系统是数据仓库系统最主要的应用，专门设计用于支持复杂的分析操作，侧重对决策人员和高层管理人员的决策支持，可以根据分析人员的要求快速、灵活地进行大数据量的复杂查询处理，并且以一种直观而易懂的形式将查询结果提供给决策人员，以便他们准确掌握企业（公司）的经营状况，了解对象的需求，制定正确的方案。</span><img src ="http://www.blogjava.net/stevenjohn/aggbug/427690.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2015-10-11 22:05 <a href="http://www.blogjava.net/stevenjohn/archive/2015/10/11/427690.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>事务并发、事务隔离级别 </title><link>http://www.blogjava.net/stevenjohn/archive/2015/01/31/422617.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Sat, 31 Jan 2015 10:20:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2015/01/31/422617.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/422617.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2015/01/31/422617.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/422617.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/422617.html</trackback:ping><description><![CDATA[<p><span style="font-family: 宋体;">并发问题可归纳为以下几类</span><span style="font-family: Calibri;">:</span></p><p>&nbsp;</p><p><span style="font-family: Calibri;">A.</span><span style="font-family: 宋体;">丢失更新：撤销一个事务时，把其他事务已提交的更新数据覆盖（</span><span style="font-family: Calibri;">A</span><span style="font-family: 宋体;">和</span><span style="font-family: Calibri;">B</span><span style="font-family: 宋体;">事务并发执行，</span><span style="font-family: Calibri;">A</span><span style="font-family: 宋体;">事务执行更新后，提交；</span><span style="font-family: Calibri;">B</span><span style="font-family: 宋体;">事务在</span><span style="font-family: Calibri;">A</span><span style="font-family: 宋体;">事务更新后，</span><span style="font-family: Calibri;">B</span><span style="font-family: 宋体;">事务结束前也做了对该行数据的更新操作，然后回滚，则两次更新操作都丢失了）。</span><span style="font-family: Calibri;"><br /><br />B.</span><span style="font-family: 宋体;">脏读：一个事务读到另一个事务未提交的更新数据（</span><span style="font-family: Calibri;">A</span><span style="font-family: 宋体;">和</span><span style="font-family: Calibri;">B</span><span style="font-family: 宋体;">事务并发执行，</span><span style="font-family: Calibri;">B</span><span style="font-family: 宋体;">事务执行更新后，</span><span style="font-family: Calibri;">A</span><span style="font-family: 宋体;">事务查询</span><span style="font-family: Calibri;">B</span><span style="font-family: 宋体;">事务没有提交的数据，</span><span style="font-family: Calibri;">B</span><span style="font-family: 宋体;">事务回滚，则</span><span style="font-family: Calibri;">A</span><span style="font-family: 宋体;">事务得到的数据不是数据库中的真实数据。也就是脏数据，即和数据库中不一致的数据）。</span><br /><br /><span style="font-family: Calibri;">C.</span><span style="font-family: 宋体;">不可重复读：一个事务读到另一个事务已提交的更新数据（</span><span style="font-family: Calibri;">A</span><span style="font-family: 宋体;">和</span><span style="font-family: Calibri;">B</span><span style="font-family: 宋体;">事务并发执行，</span><span style="font-family: Calibri;">A</span><span style="font-family: 宋体;">事务查询数据，然后</span><span style="font-family: Calibri;">B</span><span style="font-family: 宋体;">事务更新该数据，</span><span style="font-family: Calibri;">A</span><span style="font-family: 宋体;">再次查询该数据时，发现该数据变化了）。</span><span style="font-family: Calibri;"><br /><br />D. </span><span style="font-family: 宋体;">覆盖更新：这是不可重复读中的特例，一个事务覆盖另一个事务已提交的更新数据（即</span><span style="font-family: Calibri;">A</span><span style="font-family: 宋体;">事务更新数据，然后</span><span style="font-family: Calibri;">B</span><span style="font-family: 宋体;">事务更新该数据，</span><span style="font-family: Calibri;">A</span><span style="font-family: 宋体;">事务查询发现自己更新的数据变了）。</span></p><p>&nbsp;</p><p><span style="font-family: Calibri;">E.</span><span style="font-family: 宋体;">虚读（</span><strong><span style="color: #555555; font-family: 宋体;">幻读</span></strong><span style="font-family: 宋体;">）：一个事务读到另一个事务已提交的新插入的数据（</span><span style="font-family: Calibri;">A</span><span style="font-family: 宋体;">和</span><span style="font-family: Calibri;">B</span><span style="font-family: 宋体;">事务并发执行，</span><span style="font-family: Calibri;">A</span><span style="font-family: 宋体;">事务查询数据，</span><span style="font-family: Calibri;">B</span><span style="font-family: 宋体;">事务插入或者删除数据，</span><span style="font-family: Calibri;">A</span><span style="font-family: 宋体;">事务再次查询发现结果集中有以前没有的数据或者以前有的数据消失了）。</span><br /><br /><span style="font-family: 宋体;">数据库系统提供了四种事务隔离级别供用户选择：</span><span style="font-family: Calibri;"><br /><br />A.Serializable</span><span style="font-family: 宋体;">（串行化）：一个事务在执行过程中完全看不到其他事务对数据库所做的更新（事务执行的时候不允许别的事务并发执行。事务串行化执行，事务只能一个接着一个地执行，而不能并发执行。）。</span><span style="font-family: Calibri;"><br /><br />B.Repeatable Read</span><span style="font-family: 宋体;">（可重复读）：一个事务在执行过程中可以看到其他事务已经提交的新插入的记录，但是不能看到其他其他事务对已有记录的更新。</span><span style="font-family: Calibri;"><br /><br />C.Read Commited</span><span style="font-family: 宋体;">（读已提交数据）：一个事务在执行过程中可以看到其他事务已经提交的新插入的记录，而且能看到其他事务已经提交的对已有记录的更新。</span><span style="font-family: Calibri;"><br /><br />D.Read Uncommitted</span><span style="font-family: 宋体;">（读未提交数据）：一个事务在执行过程中可以看到其他事务没有提交的新插入的记录，而且能看到其他事务没有提交的对已有记录的更新。</span></p><p>&nbsp;</p><table border="1" cellpadding="0"><tbody><tr><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;">&nbsp;</span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="font-size: 12px;"><span style="line-height: 150%; font-family: 宋体;">丢失更新</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="font-size: 12px;"><span style="line-height: 150%; font-family: 宋体;">脏读</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="font-size: 12px;"><span style="line-height: 150%; font-family: 宋体;">非重复读</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="font-size: 12px;"><span style="line-height: 150%; font-family: 宋体;">覆盖更新</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="font-size: 12px;"><span style="line-height: 150%; font-family: 宋体;">幻像读</span></span></p></td></tr><tr><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="font-size: 12px;"><span style="line-height: 150%; font-family: 宋体;">未提交读</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">Y</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">Y</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">Y</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">Y</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">Y</span></span></p></td></tr><tr><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="font-size: 12px;"><span style="line-height: 150%; font-family: 宋体;">已提交读</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">N</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">N</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">Y</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">Y</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">Y</span></span></p></td></tr><tr><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="font-size: 12px;"><span style="line-height: 150%; font-family: 宋体;">可重复读</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">N</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">N</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">N</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">N</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">Y</span></span></p></td></tr><tr><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="font-size: 12px;"><span style="line-height: 150%; font-family: 宋体;">串行化</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">N</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">N</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">N</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">N</span></span></p></td><td width="67" style="padding: 0.75pt; border: #c0c0c0; width: 50pt;"><p align="center" style=" text-align: center; line-height: 150%;"><span style="line-height: 150%; font-family: Verdana, sans-serif;"><span style="font-size: 12px;">N</span></span></p></td></tr></tbody></table><p><br /><br /></p><p>&nbsp;</p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="font-size: 12px;"><span style="background-color: #ffffff;"><strong><span style="color: #330033;">隔离级别</span></strong></span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">数据库系统有四个隔离级别（大多数数据库默认级别为read commited）。对数据库使用何种隔离级别要审慎分析，因为</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">1. 维护一个最高的隔离级别虽然会防止数据的出错，但是却导致了并行度的损失，以及导致死锁出现的可能性增加。</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">2. 然而，降低隔离级别，却会引起一些难以发现的bug。</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><strong><span style="background-color: #ffffff;"><span style="color: #330033;">SERIALIZABLE（序列化）</span></span></strong></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">添加范围锁（比如表锁，页锁等，关于range lock，我也没有很深入的研究），直到transaction A结束。以此阻止其它transaction B对此范围内的insert，update等操作。</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">幻读，脏读，不可重复读等问题都不会发生。</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><strong><span style="background-color: #ffffff;"><span style="color: #330033;">REPEATABLE READ（可重复读）</span></span></strong></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">对于读出的记录，添加共享锁直到transaction A结束。其它transaction B对这个记录的试图修改会一直等待直到transaction A结束。</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">可能发生的问题：当执行一个范围查询时，可能会发生幻读。</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><strong><span style="background-color: #ffffff;"><span style="color: #330033;">READ COMMITTED（提交读）</span></span></strong></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">在transaction A中读取数据时对记录添加共享锁，但读取结束立即释放。其它transaction B对这个记录的试图修改会一直等待直到A中的读取过程结束，而不需要整个transaction A的结束。所以，在transaction A的不同阶段对同一记录的读取结果可能是不同的。</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">可能发生的问题：不可重复读。</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><strong><span style="background-color: #ffffff;"><span style="color: #330033;">READ UNCOMMITTED(未提交读)</span></span></strong></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">不添加共享锁。所以其它transaction B可以在transaction A对记录的读取过程中修改同一记录，可能会导致A读取的数据是一个被破坏的或者说不完整不正确的数据。</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">另外，在transaction A中可以读取到transaction B（未提交）中修改的数据。比如transaction B对R记录修改了，但未提交。此时，在transaction A中读取R记录，读出的是被B修改过的数据。</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">可能发生的问题：脏读。</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><strong><span style="font-size: 12px; background-color: #ffffff;"><span style="color: #330033;">问题</span></span></strong></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">我们看到，当执行不同的隔离级别时，可能会发生各种各样不同的问题。下面对它们进行总结并举例说明。</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><strong><span style="color: #330033;">幻读</span></strong></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">幻读发生在当两个完全相同的查询执行时，第二次查询所返回的结果集跟第一个查询不相同。</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">发生的情况：没有范围锁。</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">例子：</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;">&nbsp;</p><table style="line-height: 25px; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px;"><tbody><tr><td style="font-size: 1em;"><span style="color: #330033; background-color: #ffffff;">事务1</span></td><td style="font-size: 1em;"><span style="color: #330033; background-color: #ffffff;">事务2</span></td></tr><tr><td style="font-size: 1em;"><pre style="font-size: 1em;" name="code"><span style="color: #330033; background-color: #ffffff;">SELECT  * FROM users WHERE age BETWEEN 10 AND 30 </span></pre></td><td style="font-size: 1em;"><span style="color: #330033; background-color: #ffffff;"><br /></span></td></tr><tr><td style="font-size: 1em;"><span style="color: #330033; background-color: #ffffff;"><br /></span></td><td style="font-size: 1em;"><pre style="font-size: 1em;" name="code"><span style="color: #330033; background-color: #ffffff;">INSERT INTO users VALUES ( 3 , 'Bob' , 27 ); </span><pre style="color: #333333; font-size: 1em; white-space: pre-wrap; background-color: #ffffff;" name="code"><span style="color: #330033;">COMMIT;</span></pre></pre></td></tr><tr><td style="font-size: 1em;"><pre style="font-size: 1em;" name="code"><span style="color: #330033; background-color: #ffffff;">SELECT * FROM users WHERE age BETWEEN 10 AND 30;</span></pre></td></tr></tbody></table><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;">&nbsp;</p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;">&nbsp;</p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">如何避免：实行序列化隔离模式，在任何一个低级别的隔离中都可能会发生。</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><strong><span style="background-color: #ffffff;"><span style="color: #330033;">不可重复读</span></span></strong></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">在基于锁的并行控制方法中，如果在执行select时不添加读锁，就会发生不可重复读问题。</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">在多版本并行控制机制中，当一个遇到提交冲突的事务需要回退但却被释放时，会发生不可重复读问题。</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><table style="line-height: 25px; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px;"><tbody><tr><td style="font-size: 1em;"><span style="background-color: #ffffff;"><span style="color: #330033;">事务1</span></span></td><td style="font-size: 1em;"><span style="background-color: #ffffff;"><span style="color: #330033;">事务2</span></span></td></tr><tr><td style="font-size: 1em;"><pre style="font-size: 1em;" name="code"><span style="background-color: #ffffff;"><span style="color: #330033;">SELECT * FROM users WHERE id = 1; </span></span></pre></td><td style="font-size: 1em;"><span style="background-color: #ffffff;"><span style="color: #330033;"><br /></span></span></td></tr><tr><td style="font-size: 1em;"><span style="background-color: #ffffff;"><span style="color: #330033;"><br /></span></span></td><td style="font-size: 1em;"><pre style="font-size: 1em;" name="code"><span style="color: #330033; background-color: #ffffff;">UPDATE users SET age = 21 WHERE id = 1 ; COMMIT; /* in multiversion concurrency*/    control, or lock-based READ COMMITTED * </span></pre></td></tr><tr><td style="font-size: 1em;"><pre style="font-size: 1em;" name="code"><span style="background-color: #ffffff;"><span style="color: #330033;">SELECT * FROM users WHERE id = 1; </span></span></pre></td><td style="font-size: 1em;"><span style="background-color: #ffffff;"><span style="color: #330033;"><br /></span></span></td></tr><tr><td style="font-size: 1em;"><span style="background-color: #ffffff;"><span style="color: #330033;"><br /></span></span></td><td style="font-size: 1em;"><pre style="font-size: 1em;" name="code"><span style="background-color: #ffffff;"><span style="color: #330033;">COMMIT; /* lock-based REPEATABLE READ */ </span></span></pre></td></tr></tbody></table><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">在上面这个例子中，事务2提交成功，它所做的修改已经可见。然而，事务1已经读取了一个其它的值。在序列化和可重复读的隔离级别中，数据库管理系统会返回旧值，即在被事务2修改之前的值。在提交读和未提交读隔离级别下，可能会返回被更新的值，这就是&#8220;不可重复读&#8221;。</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">有两个策略可以防止这个问题的发生：</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">1. 推迟事务2的执行，直至事务1提交或者回退。这种策略在使用锁时应用。(悲观锁机制，比如用select for update为数据行加上一个排他锁)</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">2. 而在多版本并行控制中，事务2可以被先提交。而事务1，继续执行在旧版本的数据上。当事务1终于尝试提交时，数据库会检验它的结果是否和事务1、事务2顺序执行时一样。如果是，则事务1提交成功。如果不是，事务1会被回退。（乐观锁机制）</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><strong><span style="background-color: #ffffff;"><span style="color: #330033;">脏读</span></span></strong></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;"><span style="color: #330033;">脏读发生在一个事务A读取了被另一个事务B修改，但是还未提交的数据。假如B回退，则事务A读取的是无效的数据。这跟不可重复读类似，但是第二个事务不需要执行提交。&nbsp;</span></span></p><p style="line-height: 25px; padding-top: 0px; padding-bottom: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; margin-top: 0px; margin-bottom: 0px;"><span style="background-color: #ffffff;">&nbsp;</span></p><table style="line-height: 25px; font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 14px;"><tbody><tr><td style="font-size: 1em;"><span style="color: #330033; background-color: #ffffff;">事务1</span></td><td style="font-size: 1em;"><span style="color: #330033; background-color: #ffffff;">事务2</span></td></tr><tr><td style="font-size: 1em;"><pre style="font-size: 1em;" name="code"><span style="color: #330033; background-color: #ffffff;">SELECT * FROM users WHERE id = 1；</span></pre></td><td style="font-size: 1em;"><span style="color: #330033; background-color: #ffffff;"><br /></span></td></tr><tr><td style="font-size: 1em;"><span style="color: #330033; background-color: #ffffff;"><br /></span></td><td style="font-size: 1em;"><pre style="font-size: 1em;" name="code"><span style="color: #330033; background-color: #ffffff;">UPDATE users SET age = 21 WHERE id = 1 </span></pre></td></tr><tr><td style="font-size: 1em;"><pre style="font-size: 1em;" name="code"><span style="color: #330033; background-color: #ffffff;">SELECT FROM users WHERE id = 1；</span></pre></td><td style="font-size: 1em;"><span style="color: #330033; background-color: #ffffff;"><br /></span></td></tr><tr><td style="font-size: 1em;"><span style="color: #330033; background-color: #ffffff;"><br /></span></td><td style="font-size: 1em;"><pre style="font-size: 1em;" name="code"><span style="background-color: #ffffff;"><span style="color: #330033;">COMMIT; /* lock-based DIRTY READ */ </span></span></pre></td></tr></tbody></table><img src ="http://www.blogjava.net/stevenjohn/aggbug/422617.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2015-01-31 18:20 <a href="http://www.blogjava.net/stevenjohn/archive/2015/01/31/422617.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>isolation level</title><link>http://www.blogjava.net/stevenjohn/archive/2015/01/31/422616.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Sat, 31 Jan 2015 10:15:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2015/01/31/422616.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/422616.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2015/01/31/422616.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/422616.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/422616.html</trackback:ping><description><![CDATA[<h2 style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;">ANSI/ISO&nbsp; SQL的四个isolation level</h2><h3 style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;"><a name="t1" style="color: #ff9900; width: 20px; height: 20px; text-indent: 20px; background-image: url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif); background-repeat: no-repeat;"></a><span class="mw-headline" id="SERIALIZABLE">SERIALIZABLE</span></h3><h2><div style="display: inline-block;"><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;"></p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;">这是最高层次isolation level，这个层次的isolation实现了串行化的效果，即：几个Transcation在执行时，其执行效果和某个串行序执行这几个Transaction的效果是一样的。使用Serializable层次的事务，其中的查询语句在每次都必须在同样的数据上执行，从而防止了phantom read，其实现机制是range lock。与下一个层次的不同之处在于range lock。</p><span style="font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;">在基于锁的DBMS中，Serializable直到事务结束才释放select数据集上的读、写锁。而且select查询语句必须首先获得range-locks才能执行。在非锁并行的DBMS中，系统每当检测到write collision时，一次只有一个write能被写入。</span></div></h2><h3 style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;"><a name="t2" style="color: #ff9900; width: 20px; height: 20px; text-indent: 20px; background-image: url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif); background-repeat: no-repeat;"></a><strong>range lock</strong></h3><h2><div style="display: inline-block;"><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;">Range lock记录Serializable Transaction所读取的key值范围，阻止其他在这个key值范围内的记录被插入到表中。Range lock位于Index上，记录一个起始Index和一个终止Index。在Range lock锁定的Index范围内，任何Update、Insert和Delete操作都是被禁止的，从而保证了Serializable中的操作每次都在同样的数据集上进行。</p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;"></p></div></h2><h3 style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;"><a name="t3" style="color: #ff9900; width: 20px; height: 20px; text-indent: 20px; background-image: url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif); background-repeat: no-repeat;"></a><span class="mw-headline" id="REPEATABLE_READS">REPEATABLE READS</span></h3><h2><div style="display: inline-block;"><span style="font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;">在基于锁的DBMS中，Repeatable Reads直到事务结束才释放select数据集上的读、写锁。但不会使用range lock，因此会产生Phantom Read。</span><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;"></p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;"></p></div></h2><h3 style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;"><a name="t4" style="color: #ff9900; width: 20px; height: 20px; text-indent: 20px; background-image: url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif); background-repeat: no-repeat;"></a><span class="mw-headline" id="READ_COMMITTED">READ COMMITTED</span></h3><h2><div style="display: inline-block;"><span style="font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;">在基于锁的DBMS中，Read Committed直到事务结束才释放select数据集上的写锁，但读锁会在一个select完成后才被释放。和Repeatable Read一样，Read Committed不使用range lock，会产生Phantom read和Unrepeatable read。（注：这段主要参考wikipedia，我也搜索过Read Committed，基本都采用了这种说法。但我有一个疑问，既然write锁直到事务提交才释放，那么在这个阶段是不会发生update操作的，在一个事务中的多个读应该也不会产生不同的结果才对。望知之者指点一二，小弟不胜感激。）</span><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;"></p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;"></p></div></h2><h3 style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;"><a name="t5" style="color: #ff9900; width: 20px; height: 20px; text-indent: 20px; background-image: url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif); background-repeat: no-repeat;"></a><span class="mw-headline" id="READ_UNCOMMITTED">READ UNCOMMITTED</span></h3><h2><div style="display: inline-block;"><span style="font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;">这是Isolation Level的最底层，不仅会产生Phantom Read、Unrepeatable Read，还会有Dirty Read的风险。</span><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;"></p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;"></p></div></h2><h3 style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;"><a name="t6" style="color: #ff9900; width: 20px; height: 20px; text-indent: 20px; background-image: url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif); background-repeat: no-repeat;"></a><span class="mw-headline" id="READ_UNCOMMITTED"></span></h3><h2 style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;"><a name="t7" style="color: #ff9900; width: 20px; height: 20px; text-indent: 20px; background-image: url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif); background-repeat: no-repeat;"></a><span class="mw-headline" id="Read_phenomena">Read phenomena</span></h2><h2><div style="display: inline-block;"><span style="font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;">SQL 92标准将事务T1读写T2的操作分为三种，Phantom Read、Unrepeatable Read和Dirty Read</span><strong style="font-family: Arial; font-size: 14px; line-height: 26px; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Users</strong><br style="font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;" /><table class="wikitable  " style="color: #000000; font-family: Arial; font-size: 14px; line-height: 26px; background-color: #ffffff;"><tbody><tr><th>id</th><th>name</th><th>age</th></tr><tr><td>1</td><td>Joe</td><td>20</td></tr><tr><td>2</td><td>Jill</td><td>25</td></tr></tbody></table></div></h2><h3 style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;"><a name="t8" style="color: #ff9900; width: 20px; height: 20px; text-indent: 20px; background-image: url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif); background-repeat: no-repeat;"></a><span class="mw-headline" id="Dirty_reads_.28Uncommitted_Dependency.29">Dirty reads (Uncommitted Dependency)</span></h3><h2><div style="display: inline-block;"><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;"></p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;">事务T1在读取事务T2已经修改、但T2还未提交的数据时会发生Dirty Read。这个Isolation Level唯一能保证的是Update操作按顺序执行，即事务中前面的update一定比后面的update先执行。</p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;">下面的这个例子是一个典型的Dirty Read<br /></p><table style="color: #000000; font-family: Arial; line-height: 26px; font-size: 13px; background-color: #ffffff;"><tbody><tr><th>Transaction 1</th><th>Transaction 2</th></tr><tr><td><div dir="ltr" class="mw-geshi"><div class="sql source-sql"><pre class="de1" name="code" style="white-space: pre-wrap; word-wrap: break-word;"><span class="coMULTI">/* Query 1 */</span>
<span class="kw1">SELECT</span> age <span class="kw1">FROM</span> users <span class="kw1">WHERE</span> id <span class="sy0">=</span> <span class="nu0">1</span>;
<span class="coMULTI">/* will read 20 */</span>
</pre></div></div></td><td>&nbsp;</td></tr><tr><td>&nbsp;</td><td><div dir="ltr" class="mw-geshi"><div class="sql source-sql"><pre class="de1" name="code" style="white-space: pre-wrap; word-wrap: break-word;"><span class="coMULTI">/* Query 2 */</span>
<span class="kw1">UPDATE</span> users <span class="kw1">SET</span> age <span class="sy0">=</span> <span class="nu0">21</span> <span class="kw1">WHERE</span> id <span class="sy0">=</span> <span class="nu0">1</span>;
<span class="coMULTI">/* No commit here */</span>
</pre></div></div></td></tr><tr><td><div dir="ltr" class="mw-geshi"><div class="sql source-sql"><pre class="de1" name="code" style="white-space: pre-wrap; word-wrap: break-word;"><span class="coMULTI">/* Query 1 */</span>
<span class="kw1">SELECT</span> age <span class="kw1">FROM</span> users <span class="kw1">WHERE</span> id <span class="sy0">=</span> <span class="nu0">1</span>;
<span class="coMULTI">/* will read 21 */</span>
</pre></div></div></td><td>&nbsp;</td></tr><tr><td>&nbsp;</td><td><div dir="ltr" class="mw-geshi"><div class="sql source-sql"><pre class="de1" name="code" style="white-space: pre-wrap; word-wrap: break-word;"><span class="kw1">ROLLBACK</span>; <span class="coMULTI">/* lock-based DIRTY READ */</span>
</pre></div></div></td></tr></tbody></table><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;"><span class="editsection"></span><span class="mw-headline" id="Non-repeatable_reads"></span></p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;"></p></div></h2><h3 style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;"><a name="t9" style="color: #ff9900; width: 20px; height: 20px; text-indent: 20px; background-image: url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif); background-repeat: no-repeat;"></a><span class="mw-headline" id="Non-repeatable_reads">Non-repeatable reads</span></h3><h2><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;"></p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;">在一个事务T1中，如果对同一条记录读取两次而值不一样，那么就发生了Non-repeatable read。</p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;">在基于锁的DBMS中，Non-repeatable read可能在未获得read lock时进行select操作，或在select操作刚结束就释放read lock时发生。在多版本并行控制的DBMS中，non-repeatable read可能在违背&#8220;受commit conflict影响的事务必须回滚&#8220;的原则时发生。<br /></p><table style="color: #000000; font-family: Arial; line-height: 26px; font-size: 13px; background-color: #ffffff;"><tbody><tr><th>Transaction 1</th><th>Transaction 2</th></tr><tr><td><div dir="ltr"><div source-sql"=""><pre name="code" style="white-space: pre-wrap; word-wrap: break-word;">/* Query 1 */ SELECT * FROM users WHERE id = 1; </pre></div></div></td><td>&nbsp;</td></tr><tr><td>&nbsp;</td><td><div dir="ltr"><div source-sql"=""><pre name="code" style="white-space: pre-wrap; word-wrap: break-word;">/* Query 2 */ UPDATE users SET age = 21 WHERE id = 1; COMMIT; /* in multiversion concurrency    control, or lock-based READ COMMITTED */ </pre></div></div></td></tr><tr><td><div dir="ltr"><div source-sql"=""><pre name="code" style="white-space: pre-wrap; word-wrap: break-word;">/* Query 1 */ SELECT * FROM users WHERE id = 1; COMMIT; /* lock-based REPEATABLE READ */</pre></div></div></td></tr></tbody></table><div style="display: inline-block;"><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;">有两种方式来防止non-repeatable read。第一种方式用锁使T1和T2串行。另外一种方式是在多版本并行控制的DBMS中使用的。在这里，T2可以提交，而先于T2启动的T1则在自己的Snapshot（快照）里继续执行，在T1提交时，系统会检查其结果是否与T1、T2序执行的结果一样，如果一样，则T1提交，否则T1必须回滚并生成一个serialization failure。<br /></p></div></h2><h3 style="margin: 0px; padding: 0px; font-family: Arial; line-height: 26px; background-color: #ffffff;"><a name="t10" style="color: #ff9900; width: 20px; height: 20px; text-indent: 20px; background-image: url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif); background-repeat: no-repeat;"></a><span class="mw-headline" id="Phantom_reads">Phantom reads</span></h3><h2><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;">Phantom read是指在一个事务中，执行两个或多个同样的查询返回的结果集却不相同的现象。这种现象发生在没获得range lock即进行select... where....操作时，解决方法是使用range lock。<br /></p><table style="color: #000000; font-family: Arial; line-height: 26px; font-size: 13px; background-color: #ffffff;"><tbody><tr><th>Transaction 1</th><th>Transaction 2</th></tr><tr><td><div dir="ltr"><div source-sql"=""><pre name="code" style="white-space: pre-wrap; word-wrap: break-word;">/* Query 1 */ SELECT * FROM users WHERE age BETWEEN 10 AND 30; </pre></div></div></td><td>&nbsp;</td></tr><tr><td>&nbsp;</td><td><div dir="ltr"><div source-sql"=""><pre name="code" style="white-space: pre-wrap; word-wrap: break-word;">/* Query 2 */ INSERT INTO users VALUES ( 3, 'Bob', 27 ); COMMIT; </pre></div></div></td></tr><tr><td><div dir="ltr"><div source-sql"=""><pre name="code" style="white-space: pre-wrap; word-wrap: break-word;">/* Query 1 */ SELECT * FROM users WHERE age BETWEEN 10 AND 30; </pre></div></div></td><td>&nbsp;</td></tr></tbody></table><br style="font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;" /><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;">参考：</p><p style="margin: 0px; padding: 0px; font-family: Arial; font-size: 14px; font-weight: normal; line-height: 26px; background-color: #ffffff;">http://msdn.microsoft.com/en-us/library/ms191272.aspx<br />http://en.wikipedia.org/wiki/Isolation_%28database_systems%29</p></h2><img src ="http://www.blogjava.net/stevenjohn/aggbug/422616.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2015-01-31 18:15 <a href="http://www.blogjava.net/stevenjohn/archive/2015/01/31/422616.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sql 解释执行计划</title><link>http://www.blogjava.net/stevenjohn/archive/2013/12/28/408142.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Fri, 27 Dec 2013 17:40:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2013/12/28/408142.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/408142.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2013/12/28/408142.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/408142.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/408142.html</trackback:ping><description><![CDATA[<div>//oracle解释执行计划<br />SQL&gt; explain plan for select t.* from abin1 t where t.id&lt;200;</div><div>&nbsp;</div><div>Explained</div><div>&nbsp;</div><div>SQL&gt; select * from table(dbms_xplan.display);</div><div>&nbsp;</div><div>PLAN_TABLE_OUTPUT</div><div>--------------------------------------------------------------------------------</div><div>Plan hash value: 1270356885</div><div>---------------------------------------------------------------------------</div><div>| Id &nbsp;| Operation &nbsp; &nbsp; &nbsp; &nbsp; | Name &nbsp;| Rows &nbsp;| Bytes | Cost (%CPU)| Time &nbsp; &nbsp; |</div><div>---------------------------------------------------------------------------</div><div>| &nbsp; 0 | SELECT STATEMENT &nbsp;| &nbsp; &nbsp; &nbsp; | &nbsp; &nbsp;98 | &nbsp;1862 | &nbsp; &nbsp; 2 &nbsp; (0)| 00:00:01 |</div><div>|* &nbsp;1 | &nbsp;TABLE ACCESS FULL| ABIN1 | &nbsp; &nbsp;98 | &nbsp;1862 | &nbsp; &nbsp; 2 &nbsp; (0)| 00:00:01 |</div><div>---------------------------------------------------------------------------</div><div>Predicate Information (identified by operation id):</div><div>---------------------------------------------------</div><div>&nbsp; &nbsp;1 - filter("T"."ID"&lt;200)</div><div>&nbsp;</div><div>13 rows selected</div><div>&nbsp;</div><div>SQL&gt;&nbsp;<br /><br /><br />//mysql解释执行计划<br /><div>explain select t.* from user_rest t where id&lt;&gt;8&nbsp;<br /><br />//oracle收集表的统计信息<br /><div>analyze table abin1 compute statistics;</div><br /></div></div><img src ="http://www.blogjava.net/stevenjohn/aggbug/408142.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2013-12-28 01:40 <a href="http://www.blogjava.net/stevenjohn/archive/2013/12/28/408142.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SQL 注入查看表接口</title><link>http://www.blogjava.net/stevenjohn/archive/2013/04/25/398384.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Thu, 25 Apr 2013 06:29:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2013/04/25/398384.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/398384.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2013/04/25/398384.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/398384.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/398384.html</trackback:ping><description><![CDATA[<div>查看oracle表结构：<br />desc ABIN_LEE;<br />select * from user_tab_columns where table_name='ABIN_LEE';<br />select dbms_metadata.get_ddl('TABLE','ABIN_LEE') from dual;<br />select * from cols where table_name= 'ABIN_LEE';<br /><br /><br /><br /><br /><br /></div><img src ="http://www.blogjava.net/stevenjohn/aggbug/398384.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2013-04-25 14:29 <a href="http://www.blogjava.net/stevenjohn/archive/2013/04/25/398384.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据库连接池参数</title><link>http://www.blogjava.net/stevenjohn/archive/2013/03/27/397039.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Wed, 27 Mar 2013 02:32:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2013/03/27/397039.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/397039.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2013/03/27/397039.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/397039.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/397039.html</trackback:ping><description><![CDATA[<!--StartFragment -->

<div>　数据库连接池在初始化的时候会创建initialSize个连接，当有数据库操作时，会从池中取出一个连接。如果当前池中正在使用的连接数等于maxActive，则会等待一段时间，等待其他操作释放掉某一个连接，如果这个等待时间超过了maxWait，则会报错；如果当前正在使用的连接数没有达到maxActive，则判断当前是否空闲连接，如果有则直接使用空闲连接，如果没有则新建立一个连接。在连接使用完毕后，不是将其物理连接关闭，而是将其放入池中等待其他操作复用。<br />　　对于一个数据库连接池，一般包括一下属性。<br />　　<br />　　<br />　　名称 　　说明 　　备注<br />minIdle 最小活跃数 可以允许的空闲连接数目<br />maxActive 最大连接数 相当于池的大小<br />initialSize 初始化连接大小 <br />maxWait 获取连接的最大等待时间 <br />timeBetweenEvictionRunsMillis 空闲连接的最大生存时间 指定空闲连接在空闲多长时间后，关闭其物理连接<br />testWhileIdle 是否在空闲时检测连接可用性 由于网络或者数据库配置的原因（比如mysql连接的8小时限制），开启这个开关可以定期检测连接的可用性<br /></div><img src ="http://www.blogjava.net/stevenjohn/aggbug/397039.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2013-03-27 10:32 <a href="http://www.blogjava.net/stevenjohn/archive/2013/03/27/397039.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sql去除重复语句</title><link>http://www.blogjava.net/stevenjohn/archive/2012/11/21/391719.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Wed, 21 Nov 2012 15:20:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2012/11/21/391719.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/391719.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2012/11/21/391719.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/391719.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/391719.html</trackback:ping><description><![CDATA[<span style="text-align: left; widows: 2; text-transform: none; background-color: rgb(232,220,200); text-indent: 0px; font: 14px/21px simsun; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(70,70,70); word-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="Apple-style-span"> 
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">sql 单表/多表查询去除重复记录</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">单表distinct</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">多表group by</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">group by 必须放在 order by 和 limit之前，不然会报错</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">************************************************************************************</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px"><span style="line-height: 21px; word-wrap: normal; word-break: normal">1、查找表中多余的重复记录，重复记录是根据单个字段（peopleId）来判断</span></p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px"><span style="line-height: 21px; word-wrap: normal; word-break: normal">select * from people<br />where peopleId in (select &nbsp;<wbr>peopleId &nbsp;<wbr>from &nbsp;<wbr>people &nbsp;<wbr>group &nbsp;<wbr>by &nbsp;<wbr>peopleId &nbsp;<wbr>having &nbsp;<wbr>count(peopleId) &gt; 1)</span></p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px"><span style="line-height: 21px; word-wrap: normal; word-break: normal">2、删除表中多余的重复记录，重复记录是根据单个字段（peopleId）来判断，只留有rowid最小的记录<br />delete from people<br />where peopleId &nbsp;<wbr>in (select &nbsp;<wbr>peopleId &nbsp;<wbr>from people &nbsp;<wbr>group &nbsp;<wbr>by &nbsp;<wbr>peopleId &nbsp;<wbr>&nbsp;<wbr>having &nbsp;<wbr>count(peopleId) &gt; 1)<br />and rowid not in (select min(rowid) from &nbsp;<wbr>people &nbsp;<wbr>group by peopleId &nbsp;<wbr>having count(peopleId )&gt;1)</span></p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px"><span style="line-height: 21px; word-wrap: normal; word-break: normal">3、查找表中多余的重复记录（多个字段）<br />select * from vitae a<br />where (a.peopleId,a.seq) in &nbsp;<wbr>(select peopleId,seq from vitae group by peopleId,seq &nbsp;<wbr>having count(*) &gt; 1)</span></p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px"><span style="line-height: 21px; word-wrap: normal; word-break: normal">4、删除表中多余的重复记录（多个字段），只留有rowid最小的记录<br />delete from vitae a<br />where (a.peopleId,a.seq) in &nbsp;<wbr>(select peopleId,seq from vitae group by peopleId,seq having count(*) &gt; 1)<br />and rowid not in (select min(rowid) from vitae group by<span class="Apple-converted-space">&nbsp;</span>peopleId,seq having count(*)&gt;1)</span></p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px"><span style="line-height: 21px; word-wrap: normal; word-break: normal"><br />5、查找表中多余的重复记录（多个字段），不包含rowid最小的记录<br />select * from vitae a<br />where (a.peopleId,a.seq) in &nbsp;<wbr>(select peopleId,seq from vitae group by peopleId,seq having count(*) &gt; 1)<br />and rowid not in (select min(rowid) from vitae group by peopleId,seq having count(*)&gt;1)</span></p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">(二)<br />比方说<br />在A表中存在一个字段&#8220;name&#8221;，<br />而且不同记录之间的&#8220;name&#8221;值有可能会相同，<br />现在就是需要查询出在该表中的各记录之间，&#8220;name&#8221;值存在重复的项；<br />Select Name,Count(*) From A Group By Name Having Count(*) &gt; 1</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">如果还查性别也相同大则如下:<br />Select Name,sex,Count(*) From A Group By Name,sex Having Count(*) &gt; 1</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">(三)<br />方法一</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">declare @max integer,@id integer</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">declare cur_rows cursor local for select 主字段,count(*) from 表名 group by 主字段 having count(*) &gt;； 1</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">open cur_rows</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">fetch cur_rows into @id,@max</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">while @@fetch_status=0</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">begin</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">select @max = @max -1</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">set rowcount @max</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">delete from 表名 where 主字段 = @id</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">fetch cur_rows into @id,@max<br />end</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">close cur_rows</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">set rowcount 0</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">方法二</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">＂重复记录＂有两个意义上的重复记录，一是完全重复的记录，也即所有字段均重复的记录，二是部分关键字段重复的记录，比如Name字段重复，而其他字段不一定重复或都重复可以忽略。</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">1、对于第一种重复，比较容易解决，使用</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">select distinct * from tableName</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">就可以得到无重复记录的结果集。</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">如果该表需要删除重复的记录（重复记录保留1条），可以按以下方法删除</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">select distinct * into #Tmp from tableName</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">drop table tableName</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">select * into tableName from #Tmp<br />drop table #Tmp</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">发生这种重复的原因是表设计不周产生的，增加唯一索引列即可解决。</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">2、这类重复问题通常要求保留重复记录中的第一条记录，操作方法如下</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">假设有重复的字段为Name,Address，要求得到这两个字段唯一的结果集</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">select identity(int,1,1) as autoID, * into #Tmp from tableName</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">select min(autoID) as autoID into #Tmp2 from #Tmp group<span class="Apple-converted-space">&nbsp;</span>by Name,autoID</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">select * from #Tmp where autoID<span class="Apple-converted-space">&nbsp;</span>in(select autoID from #tmp2)</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">最后一个select即得到了Name，Address不重复的结果集（但多了一个autoID字段，实际写时可以写在select子句中省去此列）</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">(四)<br />查询重复</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">select * from tablename where id in (select id from tablename</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">group by id</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">having count(id) &gt; 1</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">)</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">3、查找表中多余的重复记录（多个字段）<br />select * from vitae a<br />where (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) &gt; 1)</p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">运行会产生问题，where(a.peopleId,a.seq)这样的写发是通不过的！！！</p></span><img src ="http://www.blogjava.net/stevenjohn/aggbug/391719.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2012-11-21 23:20 <a href="http://www.blogjava.net/stevenjohn/archive/2012/11/21/391719.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一道关于员工与部门查询的SQL笔试题 </title><link>http://www.blogjava.net/stevenjohn/archive/2012/07/18/383395.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Wed, 18 Jul 2012 06:05:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2012/07/18/383395.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/383395.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2012/07/18/383395.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/383395.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/383395.html</trackback:ping><description><![CDATA[<span style="text-align: left; widows: 2; text-transform: none; background-color: rgb(255,255,255); text-indent: 0px; font: 14px/26px Arial; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(51,51,51); word-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="Apple-style-span">
<p>create table dept<br />(<br />deptno varchar(10) primary key,<br />dname varchar(10)<br />);<br />create table emp<br />(<br />empno varchar(10) primary key,<br />ename varchar(10),<br />job varchar(10),<br />mgr varchar(10),<br />sal varchar(10),<br />deptno varchar(10) references dept(deptno)<br />);<br />drop table dept;<br />drop table emp;<br />insert into dept values ('1','事业部');<br />insert into dept values ('2','销售部');<br />insert into dept values ('3','技术部');</p>
<p><span style="font-family: 宋体">insert into emp values ('01','jacky','clerk','tom','1000','1');<br />insert into emp values ('02','tom','clerk','','2000','1');<br />insert into emp values ('07','biddy','clerk','','2000','1');<br />insert into emp values ('03','jenny','sales','pretty','600','2');<br />insert into emp values ('04','pretty','sales','','800','2');<br />insert into emp values ('05','buddy','jishu','canndy','1000','3');<br />insert into emp values ('06','canndy','jishu','','1500','3');<br />select * from dept;<br />select * from emp;</span></p>
<p>&nbsp;</p>
<p>1.列出emp表中各部门的部门号，最高工资，最低工资</p>
<p>&nbsp; select e.deptno ,max(sal) ,min(sal) from emp as e group&nbsp; by e.deptno;</p>
<p>&nbsp;&nbsp;解析：<span style="color: rgb(255,0,0)">各部门</span><span class="Apple-converted-space">&nbsp;</span>提示：分组查询，所以用group by</p>
<p>&nbsp;</p>
<p>2 列出emp表中各部门job为'CLERK'的员工的最低工资，最高工资<br />&nbsp;&nbsp; select e.deptno ,max(sal) ,min(sal) from emp as e where e.job="CLERK" group&nbsp; by e.deptno;</p>
<p>&nbsp;&nbsp; 解析：<span style="color: rgb(255,0,0)">各部门</span><span class="Apple-converted-space">&nbsp;</span>提示：分组查询，<span class="Apple-converted-space">&nbsp;</span><span style="color: rgb(255,0,0)">job</span>提示：条件查询，所以用到 group by 和 where</p>
<p>&nbsp;</p>
<p>3 对于emp中最低工资小于2000的部门，列出job为'CLERK'的员工的部门号，最低工资，最高工资</p>
<p>&nbsp;&nbsp; select b.deptno ,max(sal) ,min(sal) from emp as b where b.job="CLERK"<span class="Apple-converted-space">&nbsp;</span><br />&nbsp;&nbsp;<span class="Apple-converted-space">&nbsp;</span><span style="color: rgb(255,0,0)">and<span class="Apple-converted-space">&nbsp;</span></span>(select min(sal) from emp as a where a.deptno=b.deptno)&lt;2000 group&nbsp; by b.deptno;</p>
<p>&nbsp;&nbsp; 解析：以上面两个题为基础，&#8220;<span style="color: rgb(255,0,0)">emp中最低工资小于2000的部门</span>&#8221;只是一个条件而已。</p>
<p>&nbsp;</p>
<p>4 据部门号由高而低，工资有低而高列出每个员工的姓名，部门号，工资</p>
<p>&nbsp;&nbsp; select * from emp as b order by b.deptno desc ,b.sal asc;</p>
<p>&nbsp;&nbsp;&nbsp;解析：&#8220;<span style="color: rgb(255,0,0)">部门号由高而低，工资有低</span>&#8221;提示：需要排序，所以用到 order by 和 desc asc</p>
<p>&nbsp;</p>
<p>5 列出'buddy'所在部门中每个员工的姓名与部门号</p>
<p>&nbsp;&nbsp; select * from emp as b where b.deptno=(select a.deptno from emp as a where a.ename="buddy");</p>
<p>&nbsp;&nbsp; 解析：&#8220;'buddy'所在部门&#8221;提示找出他所在的部门号，所以可以理解&#8220;找出所有和buddy在同一部门的所有人&#8221;</p>
<p>&nbsp;</p>
<p>6 列出每个员工的姓名，工作，部门号，部门名</p>
<p>&nbsp;&nbsp; select ename,job,dept.deptno,dept.dname from emp,dept where emp.deptno=dept.deptno;</p>
<p>&nbsp;</p>
<p>7 列出emp中工作为'CLERK'的员工的姓名，工作，部门号，部门名</p>
<p>&nbsp;&nbsp; select ename,job,dept.deptno,dept.dname from emp,dept where emp.deptno=dept.deptno where job="CLERK";</p>
<p>&nbsp;</p>
<p>8 对于emp中有管理者的员工，列出姓名，管理者姓名（管理者外键为mgr）</p>
<p>&nbsp; select a.deptno,a.ename ,b.ename from emp as a,emp as b where a.mgr is not null and a.mgr=b.ename;</p>
<p>&nbsp; 解析：本句可以理解&#8220;一个员工他也是领导，所以emp.ename,emp.mgr 都有值并且有相等的员工&#8221;</p>
<p>&nbsp;</p>
<p>9 对于dept表中，列出所有部门名，部门号，同时列出各部门工作为'CLERK'的员工名与工作</p>
<p>&nbsp; select a.deptno ,a.dname, b.ename ,b.job from dept as a,emp as b where a.deptno=b.deptno and b.job="clerk";</p>
<p>&nbsp;&nbsp;解析：连表即可<br /><br /><br /><br /><a href="http://blog.csdn.net/shiyuntian_wang/article/details/4636799">http://blog.csdn.net/shiyuntian_wang/article/details/4636799</a><br /><br /><br /><br /><br /><br /><span style="text-align: left; widows: 2; text-transform: none; background-color: rgb(243,248,251); text-indent: 0px; font: 14px/21px simsun; white-space: normal; orphans: 2; letter-spacing: normal; color: rgb(68,68,68); word-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="Apple-style-span"></p>
<p style="padding-bottom: 0px; line-height: 21px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 5px; padding-left: 0px; padding-right: 0px; word-wrap: normal; border-top-width: 0px; border-bottom-width: 0px; word-break: normal; border-left-width: 0px; padding-top: 0px">建表：</p><pre style="white-space: normal">DEPARTMENTS: DEPARTMENT_ID(primary key), DEPARTMENT_NAME, LOCATION</pre><pre style="white-space: normal">EMPLOYEES: EMPLOYEE_ID(primary key), EMPLOYEE_NAME, EMPLOYEE_JOB, MANAGER, SALARY, DEPARTMENT_ID</pre>
<ol style="padding-bottom: 0px; border-right-width: 0px; list-style-type: none; margin: 0px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: decimal; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px">列出EMPLOYEES表中各部门的部门号，最高工资，最低工资</li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"><pre style="white-space: normal">select max(SALARY) as 最高工资,min(SALARY) as 最低工资,DEPARTMENT_ID from EMPLOYEES group by DEPARTMENT_ID;</pre></li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: decimal; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px">列出EMPLOYEES表中各部门EMPLOYEE_JOB为'CLERK'的员工的最低工资，最高工资</li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"><pre style="white-space: normal">select max(SALARY) as 最高工资,min(SALARY) as 最低工资,DEPARTMENT_ID as 部门号 from EMPLOYEES where EMPLOYEE_JOB = 'CLERK' group by DEPARTMENT_ID;</pre></li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: decimal; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px">对于EMPLOYEES中最低工资小于1000的部门，列出EMPLOYEE_JOB为'CLERK'的员工的部门号，最低工资，最高工资</li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"><pre style="white-space: normal">select max(SALARY) as 最高工资,min(SALARY) as 最低工资,DEPARTMENT_ID as 部门号 from EMPLOYEES as b where EMPLOYEE_JOB ='CLERK' and 1000&gt;(select min(SALARY) from EMPLOYEES as a where a.DEPARTMENT_ID = b.DEPARTMENT_ID) group by b.DEPARTMENT_ID</pre></li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: decimal; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px">根据部门号由高而低，工资有低而高列出每个员工的姓名，部门号，工资</li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"><pre style="white-space: normal">select DEPARTMENT_ID as 部门号,EMPLOYEE_NAME as 姓名,SALARY as 工资 from EMPLOYEES order by DEPARTMENT_ID desc,SALARY asc</pre></li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: decimal; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px">列出'张三'所在部门中每个员工的姓名与部门号</li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"><pre style="white-space: normal">select EMPLOYEE_NAME,DEPARTMENT_ID from EMPLOYEES where DEPARTMENT_ID = (select DEPARTMENT_ID from EMPLOYEES where EMPLOYEE_NAME = '张三')</pre></li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: decimal; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px">列出每个员工的姓名，工作，部门号，部门名</li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"><pre style="white-space: normal">select EMPLOYEE_NAME,EMPLOYEE_JOB,EMPLOYEES.DEPARTMENT_ID,DEPARTMENTS.DEPARTMENT_NAME from EMPLOYEES,DEPARTMENTS where EMPLOYEES.DEPARTMENT_ID = DEPARTMENTS.DEPARTMENT_ID</pre></li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: decimal; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px">列出EMPLOYEES中工作为'CLERK'的员工的姓名，工作，部门号，部门名</li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"><pre style="white-space: normal">select EMPLOYEE_NAME,EMPLOYEE_JOB,DEPARTMENTS.DEPARTMENT_ID,DEPARTMENT_NAME from EMPLOYEES,DEPARTMENTS where DEPARTMENTS.DEPARTMENT_ID = EMPLOYEES.DEPARTMENT_ID and DEPARTMENT_JOB = 'CLERK'</pre></li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: decimal; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px">对于EMPLOYEES中有管理者的员工，列出姓名，管理者姓名（管理者外键为MANAGER）</li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"><pre style="white-space: normal">select a.EMPLOYEE_NAME as 姓名,b.EMPLOYEE_NAME as 管理者 from EMPLOYEES as a,EMPLOYEES as b where a.MANAGER is not null and a.MANAGER = b.EMPLOYEE_ID</pre><pre style="white-space: normal"></pre></li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: decimal; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px">对于DEPARTMENTS表中，列出所有部门名，部门号，同时列出各部门工作为'CLERK'的员工名与工作</li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"><pre style="white-space: normal">select DEPARTMENT_NAME as 部门名,DEPARTMENTS.DEPARTMENT_ID as 部门号,EMPLOYEE_NAME as 员工名,EMPLOYEE_JOB as 工作 from DEPARTMENTS,EMPLOYEES where DEPARTMENTS.DEPARTMENT_ID *= EMPLOYEES.DEPARTMENT_ID and EMPLOYEE_JOB = 'CLERK'</pre><pre style="white-space: normal"></pre></li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: decimal; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px">对于工资高于本部门平均水平的员工，列出部门号，姓名，工资，按部门号排序</li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"><pre style="white-space: normal">select a.DEPARTMENT_ID as 部门号,a.EMPLOYEE_NAME as 姓名,a.SALARY as 工资 from EMPLOYEES as a where a.SALARY&gt;(select avg(SALARY) from EMPLOYEES as b where a.DEPARTMENT_ID = b.DEPARTMENT_ID) order by a.DEPARTMENT_ID</pre></li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: decimal; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px">对于EMPLOYEES，列出各个部门中平均工资高于本部门平均水平的员工数和部门号，按部门号排序</li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"><pre style="white-space: normal">select count(a.SALARY) as 员工数,a.DEPARTMENT_ID as 部门号 from EMPLOYEES as a where a.SALARY&gt;(select avg(SALARY) from EMPLOYEES as b where a.DEPARTMENT_ID = b.DEPARTMENT_ID) group by a.DEPARTMENT_ID order by a.DEPARTMENT_ID</pre></li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: decimal; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px">对于EMPLOYEES中工资高于本部门平均水平，人数多与1人的，列出部门号，人数，按部门号排序</li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"><pre style="white-space: normal">select count(a.EMPLOYEE_ID) as 员工数,a.DEPARTMENT_ID as 部门号,avg(SALARY) as 平均工资 from EMPLOYEES as a where (select count(c.EMPLOYEE_ID) from EMPLOYEES as c where c.DEPARTMENT_ID = a.DEPARTMENT_ID and c.SALARY&gt;(select avg(SALARY) from EMPLOYEES as b where c.DEPARTMENT_ID = b.DEPARTMENT_ID))&gt;1 group by a.DEPARTMENT_ID order by a.DEPARTMENT_ID</pre></li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: decimal; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px">对于EMPLOYEES中低于自己工资至少5人的员工，列出其部门号，姓名，工资，以及工资少于自己的人数</li><li style="padding-bottom: 0px; border-right-width: 0px; list-style-type: none; margin: 0px 0px 0px 30px; padding-left: 0px; padding-right: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px"><pre style="white-space: normal">select a.DEPARTMENT_ID,a.EMPLOYEE_NAME,a.SALARY,(select count(b.EMPLOYEE_NAME) from EMPLOYEES as b where b.SALARY &lt; a.SALARY) as 人数 from EMPLOYEES as a where (select count(b.EMPLOYEE_NAME) from EMPLOYEES as b where b.SALARY&lt;a.SALARY)&gt;5</pre></li></ol>
<p></span><a href="http://blog.sina.com.cn/s/blog_4979ec3e0100r574.html">http://blog.sina.com.cn/s/blog_4979ec3e0100r574.html</a><br /></p></span><img src ="http://www.blogjava.net/stevenjohn/aggbug/383395.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2012-07-18 14:05 <a href="http://www.blogjava.net/stevenjohn/archive/2012/07/18/383395.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sql 常见面试题一</title><link>http://www.blogjava.net/stevenjohn/archive/2012/07/08/382513.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Sun, 08 Jul 2012 02:39:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2012/07/08/382513.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/382513.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2012/07/08/382513.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/382513.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/382513.html</trackback:ping><description><![CDATA[<div>　经常会看到这样的SQL面试题，请用一条SQL语句统计出学生的总总成绩，请用一条sql语句删除表中重复的内容，但第一条保留。最近得闲，就试着写了这么个demo，今天来这和大家分享下，如果大家有其他的sql题也可以拿出来大家一起讨论，一起分享。 <p>&nbsp;&nbsp; &nbsp; 先创建一个表：</p></div><div>CREATE TABLE [dbo].[Score](<br />&nbsp;&nbsp;&nbsp; [ID] [int] IDENTITY(1,1) PRIMARY KEY&nbsp; NOT NULL,<br />&nbsp;&nbsp;&nbsp; [Name] [nvarchar](50) NULL,<br />&nbsp;&nbsp;&nbsp; [CID] [int] NULL,<br />&nbsp;&nbsp;&nbsp; [Score] [int] NULL<br />&nbsp;）<br /><br /><div>INSERT INTO [Test].[dbo].[Score]([Name],[CID],[Score])VALUES('张三',1,60)<br />INSERT INTO [Test].[dbo].[Score]([Name],[CID],[Score])VALUES('张三',2,70)<br />INSERT INTO [Test].[dbo].[Score]([Name],[CID],[Score])VALUES('张三',3,80)<br />INSERT INTO [Test].[dbo].[Score]([Name],[CID],[Score])VALUES('张三',4,90)<br /><br />INSERT INTO [Test].[dbo].[Score]([Name],[CID],[Score])VALUES('李四',1,60)<br />INSERT INTO [Test].[dbo].[Score]([Name],[CID],[Score])VALUES('李四',2,70)<br />INSERT INTO [Test].[dbo].[Score]([Name],[CID],[Score])VALUES('李四',3,80)<br />INSERT INTO [Test].[dbo].[Score]([Name],[CID],[Score])VALUES('李四',4,90)<br /><br />INSERT INTO [Test].[dbo].[Score]([Name],[CID],[Score])VALUES('王五',1,60)<br />INSERT INTO [Test].[dbo].[Score]([Name],[CID],[Score])VALUES('王五',2,70)<br />INSERT INTO [Test].[dbo].[Score]([Name],[CID],[Score])VALUES('王五',3,80)<br />INSERT INTO [Test].[dbo].[Score]([Name],[CID],[Score])VALUES('王五',4,90)</div><br /><br /><div><p>好了，准备工作做完了，下面我们来写两条Sql语句，解决开始提出的那两个问题</p> <p>A、统计学生的成绩</p>  <div> <pre><div><span style="color: #0000ff;">select</span><span style="color: #000000;"> name,</span><span style="color: #ff00ff;">SUM</span><span style="color: #000000;">(Score)Score </span><span style="color: #0000ff;">from</span><span style="color: #000000;"> Score </span><span style="color: #0000ff;">group</span> <span style="color: #0000ff;">by</span><span style="color: #000000;"> Name</span></div></pre> </div>  <p>B、删除表中重复的记录，因为这表中的name是有重复的，所以我们就直接用这表来test</p>  <div> <pre><div><span style="color: #0000ff;">delete</span> <span style="color: #0000ff;">from</span><span style="color: #000000;"> Score </span><span style="color: #0000ff;">where</span><span style="color: #000000;"> Name </span><span style="color: #808080;">in</span>&nbsp;</div><div><span style="color: #000000;">(</span><span style="color: #0000ff;">select</span><span style="color: #000000;"> Name </span><span style="color: #0000ff;">from</span><span style="color: #000000;"> Score </span><span style="color: #0000ff;">group</span> <span style="color: #0000ff;">by</span><span style="color: #000000;"> Name </span><span style="color: #0000ff;">having</span> <span style="color: #ff00ff;">COUNT</span><span style="color: #000000;">(name)</span><span style="color: #808080;">&gt;</span><span style="color: #800000; font-weight: bold;">0</span><span style="color: #000000;">)</span><span style="color: #808080;">and</span><span style="color: #000000;"> ID&nbsp;</span></div><div>&nbsp;<span style="color: #808080;">not</span> <span style="color: #808080;">in</span><span style="color: #000000;"> (</span><span style="color: #0000ff;">select</span> <span style="color: #ff00ff;">MIN</span><span style="color: #000000;">(id) </span><span style="color: #0000ff;">from</span><span style="color: #000000;"> Score </span><span style="color: #0000ff;">group</span> <span style="color: #0000ff;">by</span><span style="color: #000000;"> Name </span><span style="color: #0000ff;">having</span> <span style="color: #ff00ff;">COUNT</span><span style="color: #000000;">(Name)</span><span style="color: #808080;">&gt;</span><span style="color: #800000; font-weight: bold;">0</span><span style="color: #000000;">)</span></div></pre> </div> 好了，两条语句解决了两个问题. </div></div><img src ="http://www.blogjava.net/stevenjohn/aggbug/382513.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2012-07-08 10:39 <a href="http://www.blogjava.net/stevenjohn/archive/2012/07/08/382513.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Sql常见面试题</title><link>http://www.blogjava.net/stevenjohn/archive/2012/07/08/382511.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Sun, 08 Jul 2012 02:26:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2012/07/08/382511.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/382511.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2012/07/08/382511.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/382511.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/382511.html</trackback:ping><description><![CDATA[<div>Sql常见面试题（总结）<br />1.用一条SQL语句 查询出每门课都大于80分的学生姓名&nbsp;&nbsp;<br />name&nbsp; &nbsp;kecheng&nbsp; &nbsp;fenshu <br />张三&nbsp; &nbsp;&nbsp;&nbsp;语文&nbsp; &nbsp;&nbsp; &nbsp; 81<br />张三&nbsp; &nbsp;&nbsp;&nbsp;数学&nbsp; &nbsp;&nbsp; &nbsp; 75<br />李四&nbsp; &nbsp;&nbsp;&nbsp;语文&nbsp; &nbsp;&nbsp; &nbsp; 76<br />李四&nbsp; &nbsp;&nbsp;&nbsp;数学&nbsp; &nbsp;&nbsp; &nbsp; 90<br />王五&nbsp; &nbsp;&nbsp;&nbsp;语文&nbsp; &nbsp;&nbsp; &nbsp; 81<br />王五&nbsp; &nbsp;&nbsp;&nbsp;数学&nbsp; &nbsp;&nbsp; &nbsp; 100<br />王五&nbsp; &nbsp;&nbsp;&nbsp;英语&nbsp; &nbsp;&nbsp; &nbsp; 90<br /><br />A: select distinct name from table&nbsp;&nbsp;where&nbsp;&nbsp;name not in (select distinct name from table where fenshu&lt;=80)<br /><br />2.学生表 如下:<br />自动编号&nbsp; &nbsp;学号&nbsp; &nbsp;姓名 课程编号 课程名称 分数<br />1&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;2005001&nbsp;&nbsp;张三&nbsp;&nbsp;0001&nbsp; &nbsp;&nbsp; &nbsp;数学&nbsp; &nbsp; 69<br />2&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;2005002&nbsp;&nbsp;李四&nbsp;&nbsp;0001&nbsp; &nbsp;&nbsp; &nbsp;数学&nbsp; &nbsp; 89<br />3&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;2005001&nbsp;&nbsp;张三&nbsp;&nbsp;0001&nbsp; &nbsp;&nbsp; &nbsp;数学&nbsp; &nbsp; 69<br />删除除了自动编号不同,其他都相同的学生冗余信息<br /><br />A: delete tablename where 自动编号 not in(select min(自动编号) from tablename group by 学号,姓名,课程编号,课程名称,分数)<br />一个叫department的表，里面只有一个字段name,一共有4条纪录，分别是a,b,c,d,对应四个球对，现在四个球对进行比赛，用一条sql语句显示所有可能的比赛组合.<br />你先按你自己的想法做一下，看结果有我的这个简单吗？<br />答：select a.name, b.name <br />from team a, team b <br />where a.name &lt; b.name<br /><br />请用SQL语句实现：从TestDB数据表中查询出所有月份的发生额都比101科目相应月份的发生额高的科目。请注意：TestDB中有很多科目，都有1－12月份的发生额。<br />AccID：科目代码，Occmonth：发生额月份，DebitOccur：发生额。<br /><span href="http://www.cnblogs.com/qindgfly/archive/2008/07/17/tag.php?name=%CA%FD%BE%DD%BF%E2">数据库</span>名：JcyAudit，数据集：Select * from TestDB<br />答：select a.*<br />from TestDB a <br />,(select Occmonth,max(DebitOccur) Debit101ccur from TestDB where AccID='101' group by Occmonth) b<br />where a.Occmonth=b.Occmonth and a.DebitOccur&gt;b.Debit101ccur<br />************************************************************************************<br />面试题：怎么把这样一个表儿<br />year&nbsp;&nbsp;month amount<br />1991&nbsp; &nbsp;1&nbsp; &nbsp;&nbsp;&nbsp;1.1<br />1991&nbsp; &nbsp;2&nbsp; &nbsp;&nbsp;&nbsp;1.2<br />1991&nbsp; &nbsp;3&nbsp; &nbsp;&nbsp;&nbsp;1.3<br />1991&nbsp; &nbsp;4&nbsp; &nbsp;&nbsp;&nbsp;1.4<br />1992&nbsp; &nbsp;1&nbsp; &nbsp;&nbsp;&nbsp;2.1<br />1992&nbsp; &nbsp;2&nbsp; &nbsp;&nbsp;&nbsp;2.2<br />1992&nbsp; &nbsp;3&nbsp; &nbsp;&nbsp;&nbsp;2.3<br />1992&nbsp; &nbsp;4&nbsp; &nbsp;&nbsp;&nbsp;2.4<br />查成这样一个结果<br />year m1&nbsp;&nbsp;m2&nbsp;&nbsp;m3&nbsp;&nbsp;m4<br />1991 1.1 1.2 1.3 1.4<br />1992 2.1 2.2 2.3 2.4 <br /><br />答案一、<br />select year, <br />(select amount from&nbsp;&nbsp;aaa m where month=1&nbsp;&nbsp;and m.year=aaa.year) as m1,<br />(select amount from&nbsp;&nbsp;aaa m where month=2&nbsp;&nbsp;and m.year=aaa.year) as m2,<br />(select amount from&nbsp;&nbsp;aaa m where month=3&nbsp;&nbsp;and m.year=aaa.year) as m3,<br />(select amount from&nbsp;&nbsp;aaa m where month=4&nbsp;&nbsp;and m.year=aaa.year) as m4<br />from aaa&nbsp;&nbsp;group by year<br /><br />这个是ORACLE&nbsp;&nbsp;中做的：<br />select * from (select name, year b1, lead(year) over<br />(partition by name order by year) b2, lead(m,2) over(partition by name order by year) b3,rank()over(<br />partition by name order by year) rk from t) where rk=1;<br />************************************************************************************<br />精妙的SQL语句！<br />精妙SQL语句&nbsp;&nbsp;<br />作者：不详 发文时间：2003.05.29 10:55:05 <br /><br />说明：复制表(只复制结构,源表名：a 新表名：b) <br /><br />SQL: select * into b from a where 1&lt;&gt;1 <br /><br />说明：拷贝表(拷贝数据,源表名：a 目标表名：b) <br /><br />SQL: insert into b(a, b, c) select d,e,f from b; <br /><br />说明：显示文章、提交人和最后回复时间 <br /><br />SQL: select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b <br /><br />说明：外连接查询(表名1：a 表名2：b) <br /><br />SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c <br /><br />说明：日程安排提前五分钟提醒 <br /><br />SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())&gt;5 <br /><br />说明：两张关联表，删除主表中已经在副表中没有的信息 <br /><br />SQL: <br /><br />delete from info where not exists ( select * from infobz where info.infid=infobz.infid ) <br /><br />说明：-- <br /><br />SQL: <br /><br />SELECT A.NUM, A.NAME, B.UPD_DATE, B.PREV_UPD_DATE <br /><br />FROM TABLE1, <br /><br />(SELECT X.NUM, X.UPD_DATE, Y.UPD_DATE PREV_UPD_DATE <br /><br />FROM (SELECT NUM, UPD_DATE, INBOUND_QTY, STOCK_ONHAND <br /><br />FROM TABLE2 <br /><br />WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = TO_CHAR(SYSDATE, 'YYYY/MM')) X, <br /><br />(SELECT NUM, UPD_DATE, STOCK_ONHAND <br /><br />FROM TABLE2 <br /><br />WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = <br /><br />TO_CHAR(TO_DATE(TO_CHAR(SYSDATE, 'YYYY/MM') &#166;&#166; '/01','YYYY/MM/DD') - 1, 'YYYY/MM') ) Y, <br /><br />WHERE X.NUM = Y.NUM （+） <br /><br />AND X.INBOUND_QTY + NVL(Y.STOCK_ONHAND,0) &lt;&gt; X.STOCK_ONHAND ) B <br /><br />WHERE A.NUM = B.NUM <br /><br />说明：-- <br /><br />SQL: <br /><br />select  * from studentinfo where not exists(select * from student where  studentinfo.id=student.id) and 系名称='"&amp;strdepartmentname&amp;"' and  专业名称='"&amp;strprofessionname&amp;"' order by 性别,生源地,高考总成绩 <br /><br />说明： <br /><br />从数据库中去一年的各单位电话费统计(电话费定额贺电化肥清单两个表来源） <br /><br />SQL: <br /><br />SELECT a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy') AS telyear, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '01', a.factration)) AS JAN, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '02', a.factration)) AS FRI, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '03', a.factration)) AS MAR, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '04', a.factration)) AS APR, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '05', a.factration)) AS MAY, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '06', a.factration)) AS JUE, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '07', a.factration)) AS JUL, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '08', a.factration)) AS AGU, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '09', a.factration)) AS SEP, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '10', a.factration)) AS OCT, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '11', a.factration)) AS NOV, <br /><br />SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '12', a.factration)) AS DEC <br /><br />FROM (SELECT a.userper, a.tel, a.standfee, b.telfeedate, b.factration <br /><br />FROM TELFEESTAND a, TELFEE b <br /><br />WHERE a.tel = b.telfax) a <br /><br />GROUP BY a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy') <br /><br />说明：四表联查问题： <br /><br />SQL: select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where ..... <br /><br />说明：得到表中最小的未使用的ID号 <br /><br />SQL: <br /><br />SELECT (CASE WHEN EXISTS(SELECT * FROM Handle b WHERE b.HandleID = 1) THEN MIN(HandleID) + 1 ELSE 1 END) as HandleID <br /><br />FROM Handle <br /><br />WHERE NOT HandleID IN (SELECT a.HandleID - 1 FROM Handle a)<br /><br />*******************************************************************************<br />有两个表A和B，均有key和value两个字段，如果B的key在A中也有，就把B的value换为A中对应的value<br />这道题的SQL语句怎么写？<br />update&nbsp;  &nbsp;b&nbsp; &nbsp;set&nbsp; &nbsp;b.value=(select&nbsp; &nbsp;a.value&nbsp; &nbsp;from&nbsp; &nbsp;a&nbsp; &nbsp;where&nbsp; &nbsp;a.key=b.key)&nbsp;  &nbsp;where&nbsp; &nbsp;b.id&nbsp; &nbsp;in(select&nbsp; &nbsp;b.id&nbsp; &nbsp;from&nbsp; &nbsp;b,a&nbsp; &nbsp;where&nbsp; &nbsp;b.key=a.key);<br />***************************************************************************<br />高级sql面试题<br />原表: <br />courseid coursename score <br />------------------------------------- <br />1 java 70 <br />2 oracle 90 <br />3 xml 40 <br />4 jsp 30 <br />5 servlet 80 <br />------------------------------------- <br />为了便于阅读,查询此表后的结果显式如下(及格分数为60): <br />courseid coursename score mark <br />--------------------------------------------------- <br />1 java 70 pass <br />2 oracle 90 pass <br />3 xml 40 fail <br />4 jsp 30 fail <br />5 servlet 80 pass <br />--------------------------------------------------- <br />写出此查询语句<br />没有装ＯＲＡＣＬＥ，没试过 <br />select courseid, coursename ,score ,decode（sign(score-60),-1,'fail','pass') as mark from course<br />完全正确 <br /><br />SQL&gt; desc course_v <br />Name Null? Type <br />----------------------------------------- -------- ---------------------------- <br />COURSEID NUMBER <br />COURSENAME VARCHAR2(10) <br />SCORE NUMBER <br /><br />SQL&gt; select * from course_v; <br /><br />COURSEID COURSENAME SCORE <br />---------- ---------- ---------- <br />1 java 70 <br />2 oracle 90 <br />3 xml 40 <br />4 jsp 30 <br />5 servlet 80 <br /><br />SQL&gt; select courseid, coursename ,score ,decode(sign(score-60),-1,'fail','pass') as mark from course_v; <br /><br />COURSEID COURSENAME SCORE MARK <br />---------- ---------- ---------- ---- <br />1 java 70 pass <br />2 oracle 90 pass <br />3 xml 40 fail <br />4 jsp 30 fail <br />5 servlet 80 pass<br />*******************************************************************************<br />原表: <br /><br />id proid proname <br />1 1 M <br />1 2 F <br />2 1 N <br />2 2 G <br />3 1 B <br />3 2 A <br />查询后的表: <br /><br />id pro1 pro2 <br />1 M F <br />2 N G <br />3 B A <br />写出查询语句<br />解决方案 <br /><br />sql求解 <br />表a <br />列 a1 a2 <br />记录 1 a <br />1 b <br />2 x <br />2 y <br />2 z <br />用select能选成以下结果吗？ <br />1 ab <br />2 xyz <br />使用pl/sql代码实现，但要求你组合后的长度不能超出oracle varchar2长度的限制。 <br />下面是一个例子 <br />create or replace type strings_table is table of varchar2(20); <br />/ <br />create or replace function merge (pv in strings_table) return varchar2 <br />is <br />ls varchar2(4000); <br />begin <br />for i in 1..pv.count loop <br />ls := ls || pv(i); <br />end loop; <br />return ls; <br />end; <br />/ <br />create table t (id number,name varchar2(10)); <br />insert into t values(1,'Joan'); <br />insert into t values(1,'Jack'); <br />insert into t values(1,'Tom'); <br />insert into t values(2,'Rose'); <br />insert into t values(2,'Jenny'); <br /><br />column names format a80; <br />select t0.id,merge(cast(multiset(select name from t where t.id = t0.id) as strings_table)) names <br />from (select distinct id from t) t0; <br /><br />drop type strings_table; <br />drop function merge; <br />drop table t; <br /><br /><br /><br /><br />用sql： <br /><br />Well  if you have a thoretical maximum, which I would assume you would given  the legibility of listing hundreds of employees in the way you describe  then yes. But the SQL needs to use the LAG function for each employee,  hence a hundred emps a hundred LAGs, so kind of bulky. <br /><br />This example uses a max of 6, and would need more cut n pasting to do more than that. <br /><br />SQL&gt; select deptno, dname, emps <br />2 from ( <br />3 select d.deptno, d.dname, rtrim(e.ename ||', '|| <br />4 lead(e.ename,1) over (partition by d.deptno <br />5 order by e.ename) ||', '|| <br />6 lead(e.ename,2) over (partition by d.deptno <br />7 order by e.ename) ||', '|| <br />8 lead(e.ename,3) over (partition by d.deptno <br />9 order by e.ename) ||', '|| <br />10 lead(e.ename,4) over (partition by d.deptno <br />11 order by e.ename) ||', '|| <br />12 lead(e.ename,5) over (partition by d.deptno <br />13 order by e.ename),', ') emps, <br />14 row_number () over (partition by d.deptno <br />15 order by e.ename) x <br />16 from emp e, dept d <br />17 where d.deptno = e.deptno <br />18 ) <br />19 where x = 1 <br />20 / <br /><br />DEPTNO DNAME EMPS <br />------- ----------- ------------------------------------------ <br />10 ACCOUNTING CLARK, KING, MILLER <br />20 RESEARCH ADAMS, FORD, JONES, ROONEY, SCOTT, SMITH <br />30 SALES ALLEN, BLAKE, JAMES, MARTIN, TURNER, WARD <br /><br />also <br />先create function get_a2; <br />create or replace function get_a2( tmp_a1 number) <br />return varchar2 <br />is <br />Col_a2 varchar2(4000); <br />begin <br />Col_a2:=''; <br />for cur in (select a2 from unite_a where a1=tmp_a1) <br />loop <br />Col_a2=Col_a2||cur.a2; <br />end loop; <br />return Col_a2; <br />end get_a2; <br /><br />select distinct a1 ,get_a2(a1) from unite_a <br />1 ABC <br />2 EFG <br />3 KMN<br />*******************************************************************************<br />一个SQL 面试题 <br />去年应聘一个职位未果,其间被考了一个看似简单的题,但我没有找到好的大案.<br />不知各位大虾有无好的解法?<br /><br /><br />题为:<br />有两个表, t1, t2,<br />Table t1:<br /><br />SELLER | NON_SELLER<br />----- -----<br /><br />A B<br />A C<br />A D<br />B A<br />B C<br />B D<br />C A<br />C B<br />C D<br />D A<br />D B<br />D C<br /><br /><br />Table t2:<br /><br />SELLER | COUPON | BAL<br />----- --------- ---------<br />A 9 100<br />B 9 200<br />C 9 300<br />D 9 400<br />A 9.5 100<br />B 9.5 20<br />A 10 80<br /><br /><br /><br />要求用SELECT 语句列出如下结果:------如A的SUM(BAL)为B,C,D的和,B的SUM(BAL)为A,C,D的和.......<br />且用的方法不要增加数据库负担,如用临时表等.<br /><br />NON-SELLER| COUPON | SUM(BAL) ------- --------<br />A 9 900<br />B 9 800<br />C 9 700<br />D 9 600 <br />A 9.5 20<br />B 9.5 100<br />C 9.5 120<br />D 9.5 120<br />A 10 0<br />B 10 80<br />C 10 80<br />D 10 80<br />关于论坛上那个SQL微软面试题<br />问题：<br /><br />一百个账户各有100$，某个账户某天如有支出则添加一条新记录，记录其余额。一百天后，请输出每天所有账户的余额信息<br /><br /><br />这个问题的难点在于每个用户在某天可能有多条纪录，也可能一条纪录也没有（不包括第一天）<br /><br />返回的记录集是一个100天*100个用户的纪录集<br /><br />下面是我的思路：<br /><br />1.创建表并插入测试数据：我们要求username从1-100<br />CREATE TABLE [dbo].[TABLE2] (<br />[username] [varchar] (50) NOT NULL , --用户名<br />[outdate] [datetime] NOT NULL , --日期<br />[cash] [float] NOT NULL --余额<br />) ON [PRIMARY<br /><br />declare @i int<br />set @i=1<br />while @i&lt;=100<br />&nbsp;&nbsp;begin<br />&nbsp; &nbsp; insert table2 values(convert(varchar(50),@i),'2001-10-1',100)<br />&nbsp; &nbsp; insert table2 values(convert(varchar(50),@i),'2001-11-1',50)<br />&nbsp; &nbsp; set @i=@i+1<br />&nbsp;&nbsp;end<br />insert table2 values(convert(varchar(50),@i),'2001-10-1',90)<br /><br />select * from table2 order by outdate,convert(int,username)<br /><br />2.组合查询语句：<br />a.我们必须返回一个从第一天开始到100天的纪录集：<br />如：2001-10-1（这个日期是任意的） 到 2002-1-8<br />由于第一天是任意一天，所以我们需要下面的SQL语句：<br />select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate<br />from table2<br />group by username<br />order by convert(int,username)<br />这里的奥妙在于：<br />convert(int,username)-1（记得我们指定用户名从1-100 :-))<br />group by username,min(outdate):第一天就可能每个用户有多个纪录。<br />返回的结果：<br />outdate&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />------------------------------------------------------ <br />2001-10-01 00:00:00.000<br />.........<br />2002-01-08 00:00:00.000<br /><br />b.返回一个所有用户名的纪录集：<br />select distinct username from table2 <br />返回结果：<br />username&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;<br />-------------------------------------------------- <br />1<br />10<br />100<br />......<br />99<br /><br />c.返回一个100天记录集和100个用户记录集的笛卡尔集合：<br />select * from<br />(<br />select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate<br />from table2<br />group by username<br />order by convert(int,username)<br />) as A<br />CROSS join <br />(<br />select distinct username from table2 <br />) as B<br />order by outdate,convert(int,username)<br />返回结果100*100条纪录：<br />outdate&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; username<br />2001-10-01 00:00:00.000&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;1<br />......<br />2002-01-08 00:00:00.000&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;100<br /><br />d.返回当前所有用户在数据库的有的纪录：<br />select outdate,username,min(cash) as cash from table2<br />group by outdate,username<br /><br />order by outdate,convert(int,username)<br />返回纪录：<br />outdate&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; username&nbsp; &nbsp; cash<br />2001-10-01 00:00:00.000&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;1&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 90<br />......<br />2002-01-08 00:00:00.000&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;100&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;50<br /><br />e.将c中返回的笛卡尔集和d中返回的纪录做left join:<br />select C.outdate,C.username,<br />D.cash<br />from<br />(<br />select * from<br />(<br />select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate<br />from table2<br />group by username<br />order by convert(int,username)<br />) as A<br />CROSS join <br />(<br />select distinct username from table2 <br />) as B<br />) as C<br />left join<br />(<br />select outdate,username,min(cash) as cash from table2<br />group by outdate,username<br />) as D<br />on(C.username=D.username and datediff(d,C.outdate,D.outdate)=0)<br /><br />order by C.outdate,convert(int,C.username)<br />注意：用户在当天如果没有纪录，cash字段返回NULL，否则cash返回每个用户当天的余额<br />outdate&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; username&nbsp; &nbsp; cash<br />2001-10-01 00:00:00.000&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;1&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 90<br />2001-10-01 00:00:00.000&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;2&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 100<br />......<br />2001-10-02 00:00:00.000&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;1&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 90<br />2001-10-02 00:00:00.000&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;2&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; NULL&nbsp;&nbsp;&lt;--注意这里<br />......<br /><br />2002-01-08 00:00:00.000&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;100&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;50<br /><br />f.好了，现在我们最后要做的就是，如果cash为NULL，我们要返回小于当前纪录日期的第一个用户余额(由于我们使用order by cash,所以返回top 1纪录即可，使用min应该也可以)，这个余额即为当前的余额：<br />case isnull(D.cash,0)<br />when 0 then <br />(<br />select top 1 cash from table2 where table2.username=C.username<br />and datediff(d,C.outdate,table2.outdate)&lt;0 <br />order by table2.cash<br />)<br />else D.cash<br />end as cash<br /><br />g.最后组合的完整语句就是<br />select C.outdate,C.username,<br />case isnull(D.cash,0)<br />when 0 then <br />(<br />select top 1 cash from table2 where table2.username=C.username<br />and datediff(d,C.outdate,table2.outdate)&lt;0 <br />order by table2.cash<br />)<br />else D.cash<br />end as cash<br />from<br />(<br />select * from<br />(<br />select top 100 dateadd(d,convert(int,username)-1,min(outdate)) as outdate<br />from table2<br />group by username<br />order by convert(int,username)<br />) as A<br />CROSS join <br />(<br />select distinct username from table2 <br />) as B<br />) as C<br />left join<br />(<br />select outdate,username,min(cash) as cash from table2<br />group by outdate,username<br />) as D<br />on(C.username=D.username and datediff(d,C.outdate,D.outdate)=0)<br /><br />order by C.outdate,convert(int,C.username)<br /><br />返回结果：<br />outdate&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;username&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;cash<br />2001-10-01 00:00:00.000&nbsp; &nbsp; 1&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;90<br />2001-10-01 00:00:00.000&nbsp; &nbsp; 2&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 100<br />......<br />2002-01-08 00:00:00.000&nbsp; &nbsp; 100&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; 50<br />***********************************************************************************<br />取出sql表中第31到40的记录（以自动增长ID为主键）<br />*从数据表中取出第n条到第m条的记录*/ <br /><br />declare @m int <br />declare @n int <br />declare @sql varchar(800) <br />set @m=40 <br />set @n=31 <br />set @sql='select top '+str(@m-@n+1) + '* from idetail where autoid not in( <br />select top '+ str(@n-1) + 'autoid from idetail)' <br />exec(@sql)<br /><br /><br />select top 10 * from t where id not in (select top 30 id from t order by id ) orde by id<br />--------------------------------------------------------------------------------<br />select top 10 * from t where id in (select top 40 id from t order by id) order by id desc<br /><br />*******************************************************************************<br />一道面试题,写sql语句<br /><br />有表a存储二叉树的节点,要用一条sql语句查出所有节点及节点所在的层.<br />表a <br />c1 c2 A ----------1 <br />---- ---- / \<br />A B B C --------2<br />A C / / \<br />B D D N E ------3<br />C E / \ \<br />D F F K I ---4<br />E I<br />D K<br />C N<br /><br /><br />所要得到的结果如下<br /><br />jd cs<br />----- ----<br />A 1<br />B 2<br />C 2<br />D 3<br />N 3<br />E 3<br />F 4<br />K 4<br />I 4<br />有高手指导一下,我只能用pl/sql写出来,请教用一条sql语句的写法<br />SQL&gt; select c2, level + 1 lv<br />2 from test start<br />3 with c1 = 'A'<br />4 connect by c1 = prior c2<br />5 union<br />6 select 'A', 1 from dual<br />7 order by lv;<br /><br />C2 LV<br />-- ----------<br />A 1<br />B 2<br />C 2<br />D 3<br />E 3<br />N 3<br />F 4<br />I 4<br />K 4<br /><br />已选择9行。</div><img src ="http://www.blogjava.net/stevenjohn/aggbug/382511.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2012-07-08 10:26 <a href="http://www.blogjava.net/stevenjohn/archive/2012/07/08/382511.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>经典的SQL语句面试题</title><link>http://www.blogjava.net/stevenjohn/archive/2012/07/08/382512.html</link><dc:creator>abin</dc:creator><author>abin</author><pubDate>Sun, 08 Jul 2012 02:26:00 GMT</pubDate><guid>http://www.blogjava.net/stevenjohn/archive/2012/07/08/382512.html</guid><wfw:comment>http://www.blogjava.net/stevenjohn/comments/382512.html</wfw:comment><comments>http://www.blogjava.net/stevenjohn/archive/2012/07/08/382512.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/stevenjohn/comments/commentRss/382512.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/stevenjohn/services/trackbacks/382512.html</trackback:ping><description><![CDATA[<div><p>Student(S#,Sname,Sage,Ssex) 学生表<br /> Course(C#,Cname,T#) 课程表<br /> SC(S#,C#,score) 成绩表<br /> Teacher(T#,Tname) 教师表 </p> <p>问题：<br /> 1、查询&#8220;001&#8221;课程比&#8220;002&#8221;课程成绩高的所有学生的学号；<br /> select 	a.S#<br /> from (select s#,score from SC where C#=&#8217;001&#8242;) a,<br /> 	(select s#,score from SC where C#=&#8217;002&#8242;) b<br /> where 	a.score&gt;b.score and a.s#=b.s#; </p> <p>2、查询平均成绩大于60分的同学的学号和平均成绩；<br /> select S#,avg(score)<br /> from sc<br /> group by S# having avg(score) &gt;60; </p> <p>3、查询所有同学的学号、姓名、选课数、总成绩；<br /> select Student.S#,Student.Sname,count(SC.C#),sum(score)<br /> from Student left Outer join SC on Student.S#=SC.S#<br /> group by Student.S#,Sname </p> <p>4、查询姓&#8220;李&#8221;的老师的个数；<br /> select count(distinct(Tname))<br /> from Teacher<br /> where Tname like &#8216;李%&#8217;; </p> <p>5、查询没学过&#8220;叶平&#8221;老师课的同学的学号、姓名；<br /> select Student.S#,Student.Sname<br /> from Student<br /> where S# not in (select distinct( SC.S#) from SC,Course,Teacher where   SC.C#=Course.C# and Teacher.T#=Course.T# and Teacher.Tname=&#8217;叶平&#8217;); </p> <p>6、查询学过&#8220;001&#8221;并且也学过编号&#8220;002&#8221;课程的同学的学号、姓名；<br /> select Student.S#,Student.Sname<br /> from Student,SC<br /> where Student.S#=SC.S# and SC.C#=&#8217;001&#8242;and exists( Select * from SC as SC_2 where SC_2.S#=SC.S# and SC_2.C#=&#8217;002&#8242;);<br /> 7、查询学过&#8220;叶平&#8221;老师所教的所有课的同学的学号、姓名；<br /> select S#,Sname<br /> from Student<br /> where S# in<br /> 	(select S#<br /> 	from SC ,Course ,Teacher<br /> 	where SC.C#=Course.C# and Teacher.T#=Course.T# and Teacher.Tname=&#8217;叶平&#8217;  group by S# having count(SC.C#)=(select count(C#) from Course,Teacher   where Teacher.T#=Course.T# and Tname=&#8217;叶平&#8217;)); </p> <p>8、查询所有课程成绩小于60分的同学的学号、姓名；<br /> select S#,Sname<br /> from Student<br /> where S# not in (select Student.S# from Student,SC where S.S#=SC.S# and score&gt;60); </p> <p>9、查询没有学全所有课的同学的学号、姓名；<br /> select Student.S#,Student.Sname<br /> from Student,SC<br /> where Student.S#=SC.S#<br /> group by  Student.S#,Student.Sname having count(C#) &lt;(select count(C#) from Course); </p> <p>10、查询至少有一门课与学号为&#8220;1001&#8221;的同学所学相同的同学的学号和姓名；<br /> select S#,Sname<br /> from Student,SC<br /> where Student.S#=SC.S# and C# in （select C# from SC where S#='1001'）;</p> <p>11、删除学习&#8220;叶平&#8221;老师课的SC表记录；<br /> Delect SC<br /> from course ,Teacher<br /> where Course.C#=SC.C# and Course.T#= Teacher.T# and Tname='叶平'; </p> <p>12、查询各科成绩最高和最低的分：以如下形式显示：课程ID，最高分，最低分<br /> SELECT L.C# 课程ID,L.score 最高分,R.score 最低分<br /> FROM SC L ,SC R<br /> WHERE L.C# = R.C#<br /> and<br /> L.score = (SELECT MAX(IL.score)<br />      FROM SC IL,Student  IM<br />      WHERE IL.C# = L.C# and IM.S#=IL.S#<br />      GROUP BY IL.C#)<br /> and<br /> R.Score = (SELECT MIN(IR.score)<br />     FROM SC  IR<br />     WHERE IR.C# = R.C#<br /> GROUP BY IR.C#  ); </p> <p>13、查询学生平均成绩及其名次<br /> SELECT 1+(SELECT COUNT( distinct 平均成绩)<br />     FROM (SELECT S#,AVG(score) 平均成绩<br />       	FROM SC<br />           GROUP BY S# ) T1<br />     WHERE 平均成绩 &gt; T2.平均成绩) 名次, S# 学生学号,平均成绩<br /> FROM (SELECT S#,AVG(score) 平均成绩 FROM SC GROUP BY S# ) T2<br /> ORDER BY 平均成绩 desc;</p> <p>14、查询各科成绩前三名的记录:(不考虑成绩并列情况)<br /> SELECT t1.S# as 学生ID,t1.C# as 课程ID,Score as 分数<br /> FROM SC t1<br /> WHERE score IN (SELECT TOP 3 score<br />            FROM SC<br />            WHERE t1.C#= C#<br />            ORDER BY score DESC)<br /> ORDER BY t1.C#; </p> <p>15、查询每门功成绩最好的前两名<br /> SELECT t1.S# as 学生ID,t1.C# as 课程ID,Score as 分数<br /> FROM SC t1<br /> WHERE score IN (SELECT TOP 2 score<br />           FROM SC<br />           WHERE t1.C#= C#<br />           ORDER BY score DESC )<br /> ORDER BY t1.C#;</p> <p>补充：<br /> 已经知道原表<br /> year salary<br /> &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br /> 2000 1000<br /> 2001 2000<br /> 2002 3000<br /> 2003 4000</p> <p>解：<br /> select b.year,sum(a.salary)<br /> from salary a,salary b<br /> where a.year&lt;=b.year<br /> group by b.year<br /> order by b.year;</p> <p>在面试过程中多次碰到一道SQL查询的题目，查询A(ID,Name)表中第31至40条记录，ID作为主键可能是不是连续增长的列，完整的查询语句如下：<br /> 方法一：<br /> select  top 10 *<br /> from A<br /> where ID &gt;(select max(ID) from (select  top 30 ID from A order by ID ) T) order by ID<br /> 方法二：<br /> select top 10 *<br /> from  A<br /> where ID not In (select top 30 ID from A order by ID)<br /> order by ID</p></div><img src ="http://www.blogjava.net/stevenjohn/aggbug/382512.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/stevenjohn/" target="_blank">abin</a> 2012-07-08 10:26 <a href="http://www.blogjava.net/stevenjohn/archive/2012/07/08/382512.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>