﻿<?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-享受编程，融入其中，了解本质-随笔分类-数据库</title><link>http://www.blogjava.net/alter/category/52602.html</link><description>美满 激情 醇厚</description><language>zh-cn</language><lastBuildDate>Fri, 14 Dec 2012 01:06:21 GMT</lastBuildDate><pubDate>Fri, 14 Dec 2012 01:06:21 GMT</pubDate><ttl>60</ttl><item><title>Oracle LEFT JOIN 多层级问题  </title><link>http://www.blogjava.net/alter/archive/2012/10/09/389226.html</link><dc:creator>a_alter</dc:creator><author>a_alter</author><pubDate>Tue, 09 Oct 2012 02:15:00 GMT</pubDate><guid>http://www.blogjava.net/alter/archive/2012/10/09/389226.html</guid><wfw:comment>http://www.blogjava.net/alter/comments/389226.html</wfw:comment><comments>http://www.blogjava.net/alter/archive/2012/10/09/389226.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alter/comments/commentRss/389226.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alter/services/trackbacks/389226.html</trackback:ping><description><![CDATA[例 &nbsp;如下<br />表 &nbsp;A&nbsp;<br />(1---&gt;n) 表B (B 可能为空)<br />(n----&gt;n)表C<br /><div>(n----&gt;n)表D</div><br />现在有如下问题 &nbsp;在查询的时候我们允许b为空的A数据<br />Select * from A,B where A.B_AID = B.AID(+)<br /><br />扩展查询 &nbsp;如果进行B关联C级别的条件过滤<br /><div>Select * from A,B, C where A.B_AID = B.AID(+) and B.C_AID = C.AID; &nbsp;<br /><br />这个时候C能够知道B是可以为空的， 这个时候的join效果是， 如果在A关联B &nbsp;B存在的情况下 在使用 C的join 条件进行筛选。 这个时候B为空的A条件还是可以摆查出来的。 只不过数据列B为空而已<br /><br /><span style="color: #000000; ">再进行扩展筛选 &nbsp;进行C关联D级别的条筛选</span><br /><div><span style="color: red; ">Select * from A,B,C,D where A.B_AID = B.AID(+) and B.C_AID = C.AID and C.D_AID = D.AID; &nbsp;</span><br /><br />这样的D级别的筛选就会破坏B级别的赛选。</div>这个时候测试效果就是 D 级别的join条件 会破坏 B的left join 效果。<br /><br />你可能想到改写条件如下<br /><span class="Apple-style-span" style="color: #ff0000; ">Select * from A,B,C,D where A.B_AID = B.AID(+) and B.C_AID = C.AID and C.D_AID(+) = D.AID; &nbsp;</span><br /><br /><span style="color: #008000; ">可惜我测试结果和full join 的效果是一样的，不是oracle高手， 谁知道的留个言火链接 &nbsp;谢谢<br /><br /></span>=======================================================================<br />后来找同学帮忙 &nbsp;得知他以前也遇到这情况<br />改写为如下条件<br /><div><font class="Apple-style-span" color="#ff0000"><span style="color: #008000; ">select * from (</span></font><span style="color: #008000; ">Select ....,C.D_AID from A,B,C where A.B_AID = B.AID(+) and B.C_AID = C.AID </span><span class="Apple-style-span" style="color: #008000; ">) E,D where E</span><span style="color: #008000; ">.D_AID(+) = D.AID<br /></span><span>这样就不会破坏B(+) 效果。 &nbsp;</span></div><br />个人理解就是 select 的组织数据效果。具体不清楚 欢迎发言。</div><br />=======================================================================<br />补充：<br />今天我才知道 &nbsp;left join 和 inner join 栏位是否必填还有关系。<br /><br />在这个问题上有个地方被欺骗了&nbsp;<br /><br />就是在 A Left join <strong>B </strong>&nbsp;inner JOIN C 的时候 &nbsp; 如果 B 的 C 字段是必填的话 &nbsp;那么就相当于 &nbsp;left join。 如果不是必填的话 你必须手动的指示 left join (+) &nbsp;。<br />=====================================================================<br /><span style="color: #993300;">补充 2012/10/19&nbsp;&nbsp; 发现以上的理解不全面</span><br /><br />A--B(+) 意思指B 端可为空， 如果 对B -- C 下面的元素进行赛选， 在局部看 B 和 C 的关系是两段都必须存在的， 但是在A -- B(+) 的前提下 C可以为空的,&nbsp; 所以需要使用 B --- C(+) 来进行关联&nbsp; <span style="color: #ff0000;">这样的坏处是可能会加载出 B&nbsp; (存在)-- C (不存在) 这样的错误数据。 当然如果系统中有对这种数据有确实保障的时候可以忽略该问题</span><br /><br />如果没有确切的保障的话 <br />可能就需要使用 A --- D(+) 其中D 为&nbsp; select * from B,C where B = C 这样的过滤方式， 但是这样就增加了复杂度， 你需要将可能用到的查询条件和查询结果集在D中 select 一一列出来 <br /><br />在 Select A.*,R1,R2,R3 from A ,(select B.A_Aid,c1,c2,c3,R1,R2,R3 from B,C where B.C_AID= C.Aid) D where A.Aid = B.A_Aid and c1 = ? and c2 = ? ....<br /><br />Sql 复杂度高了一点。<br /><br /><br /><br /><br /><br /><img src ="http://www.blogjava.net/alter/aggbug/389226.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alter/" target="_blank">a_alter</a> 2012-10-09 10:15 <a href="http://www.blogjava.net/alter/archive/2012/10/09/389226.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle sql 写法</title><link>http://www.blogjava.net/alter/archive/2012/09/12/387536.html</link><dc:creator>a_alter</dc:creator><author>a_alter</author><pubDate>Wed, 12 Sep 2012 04:57:00 GMT</pubDate><guid>http://www.blogjava.net/alter/archive/2012/09/12/387536.html</guid><wfw:comment>http://www.blogjava.net/alter/comments/387536.html</wfw:comment><comments>http://www.blogjava.net/alter/archive/2012/09/12/387536.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/alter/comments/commentRss/387536.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/alter/services/trackbacks/387536.html</trackback:ping><description><![CDATA[<div><div>本文用途：因为暂时没有时间去具体看oracle sql的官方文档 ，纪录oracle的一些特殊写法。 (不断更新)</div><div></div><div>1. with ... &nbsp;as ...</div><div></div><div>with querya as (select * from TB_Test)</div><div></div><div>2 &nbsp;case .. (when .. then) .... (when .. &nbsp;then) .. else ... end</div><div>&nbsp; &nbsp; SELECT FO_FULFILL_TRX_STRING.SEQUENCE_NO, AC_TYPE_ORDER.CODE, CASE</div><div>&nbsp; &nbsp; WHEN AC_TYPE_ORDER.CODE = 'SO'</div><div>&nbsp; &nbsp; THEN ( SELECT ORDER_NUMBER FROM SO_ORDER WHERE SO_ORDER.AID = FO_FULFILL_TRX_STRING.AID_ORDER_SO )</div><div>&nbsp; &nbsp; ELSE ( SELECT ORDER_NUMBER FROM PO_ORDER WHERE PO_ORDER.AID = FO_FULFILL_TRX_STRING.AID_ORDER_PO )</div><div>&nbsp; &nbsp; END ORDER_NUMBER</div><div>&nbsp; &nbsp; FROM FO_FULFILL_TRX_STRING, AC_TYPE_ORDER.CODE</div><div>------------------------------------------------------------------------------------------------------------------------------</div><div>MYSQL 正则支持</div><div>select * from tb_rule_list where expression regexp '^.*\\$\\{0}\\[3].*$';</div><div>Oracle &nbsp;正则函数支持</div><div></div><div>ORACLE中的支持正则表达式的函数主要有</div><div></div><div>&nbsp; &nbsp; REGEXP_LIKE ：与LIKE的功能相似</div><div>&nbsp; &nbsp; REGEXP_INSTR ：与INSTR的功能相似</div><div>&nbsp; &nbsp; REGEXP_SUBSTR ：与SUBSTR的功能相似</div><div>&nbsp; &nbsp; REGEXP_REPLACE ：与REPLACE的功能相</div><div></div><div>&nbsp;</div><div>------------------------------------------------------------------------------------------------------------------------------</div><div>在MYSQL 中 select 可以显示 不是group by 中的分组字段， 可以是任意的数据列，具体数据显示的是分组后的第一行数据</div><div>在ORACLE中 select 是严格的 只能显示group by 中的字段。</div><div>同样效果的两行sql --- 让自己注意提高自己的使用灵活性</div><div>1. select a.aid AAid,nvl(b.cot,0) countline from po_draft_order a,(select AID_DRAFT_ORDER_PO BAID,count(*) cot from &nbsp;po_draft_line group by AID_DRAFT_ORDER_PO) b WHERE A.AID = B.BAID(+);</div><div></div><div>2. select a.aid, (select count(*) from po_draft_line where AID_DRAFT_ORDER_PO = a.aid ) c from po_draft_order a;</div><div></div><div>-------------------------------------------------------------------------------------------------------------------------------</div><div>oracle 分级</div><div></div><div>rank()/dense_rank() &nbsp;over(partition by ... order by ...) &nbsp;加强对分组排序之后的数据的控制力。</div><div></div><div>over: &nbsp;over(...)</div><div>partition by : &nbsp;相当于group by</div><div>order by e.sal desc: &nbsp;按工资从高到低排序（使用rank()/dense_rank() 时，必须要带order by否则非法）</div><div>rank()/dense_rank(): &nbsp;分级</div><div>整个语句的意思就是：在按部门划分的基础上，按工资从高到低对雇员进行分级，&#8220;级别&#8221;由从小到大的数字表示（最小值一定为1）。&nbsp;</div><div></div><div>那么rank()和dense_rank()有什么区别呢？</div><div>rank(): &nbsp;跳跃排序，如果有两个第一级时，接下来就是第三级。</div><div>dense_rank(): &nbsp;连续排序，如果有两个第一级时，接下来仍然是第二级。</div><div></div><div>min()/max() over(partition by ...) &nbsp;// 分组最大最小值</div><div></div><div>lead()/lag() over(partition by order by) // 前后数据比较使用</div><div></div><div>lead(列名,n,m): &nbsp;当前记录后面第n行记录的&lt;列名&gt;的值，没有则默认值为m；如果不带参数n,m，则查找当前记录后面第一行的记录&lt;列名&gt;的值，没有则默认值为null。</div><div>lag(列名,n,m): &nbsp;当前记录前面第n行记录的&lt;列名&gt;的值，没有则默认值为m；如果不带参数n,m，则查找当前记录前面第一行的记录&lt;列名&gt;的值，没有则默认值为null。</div><div></div><div>主要是各个函数和over的配合使用。</div><div></div><div>-----------------------------------------------------------------------------------------------------------------------------------------------------</div><div></div><div>Oracle 的集合运算</div><div></div><div>UNION 用来合并结果集 要求返回字段是一样的。</div><div>JOIN 用来合并字段。</div><div></div><div>并集</div><div></div><div>UNION ALL, FULL JOIN -- 重复出现</div><div></div><div>UNION, INNER JOIN minus -- 一次出现</div><div>交集</div><div><div><span style="color: #333333; line-height: 28px; background-color: #ffffff; font-family: Arial; font-size: 12pt; ">intersect</span></div></div><div>差集</div><div><div><div>minus&nbsp;</div></div></div><div>笛卡尔积</div><div>CROSS JOIN<br />------------------------------------------------------------------------------------------------------------------------------<br />INNER JOIN oracle 特殊的写法 不知道在sqlserver 是否支持。<br /><div>SELECT<br />*<br />FROM (<br />&nbsp; SO_WEC_SODL_DESPATCH_HEADER AS SO_WEC_SODL_DESPATCH_HEADER_1 <br />&nbsp;&nbsp;&nbsp; INNER JOIN (<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SO_WARRANTY_ENTITLEMENT WET_1 <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INNER JOIN (SO_WARRANTY_ENTITLEMENT INNER JOIN SO_WEC_SODL <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ON SO_WARRANTY_ENTITLEMENT.AID = SO_WEC_SODL.AID_WARRANTY_ENTITLEMENT_SO<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ) ON (WET_1.AID_COMPANY = SO_WARRANTY_ENTITLEMENT.AID_COMPANY) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AND (WET_1.SEQ_ITEM_NUM = SO_WARRANTY_ENTITLEMENT.PARENT_SEQ_ITEM) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AND (WET_1.ITEM_LINE_NUM = SO_WARRANTY_ENTITLEMENT.PARENT_ITEM_NUM) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AND (WET_1.SO_LINE_NUM = SO_WARRANTY_ENTITLEMENT.PARENT_SOLINE_NUM) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AND (WET_1.SO_NUM = SO_WARRANTY_ENTITLEMENT.SO_NUM)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; INNER JOIN SO_WEC_SODL AS SO_WEC_SODL_1 ON (SO_WEC_SODL.LINE_DELIVERY_NUMBER = SO_WEC_SODL_1.LINE_DELIVERY_NUMBER) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AND (WET_1.AID = SO_WEC_SODL_1.AID_WARRANTY_ENTITLEMENT)<br />&nbsp;&nbsp;&nbsp; ) ON SO_WEC_SODL_DESPATCH_HEADER_1.AID_WEC_SODL = SO_WEC_SODL_1.AID <br />) INNER JOIN SO_WEC_SODL_DESPATCH_HEADER ON SO_WEC_SODL.AID = SO_WEC_SODL_DESPATCH_HEADER.AID_WEC_SODL</div><br />===</div><div></div><div></div><div></div></div><div><div><p><br /></p></div></div><img src ="http://www.blogjava.net/alter/aggbug/387536.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/alter/" target="_blank">a_alter</a> 2012-09-12 12:57 <a href="http://www.blogjava.net/alter/archive/2012/09/12/387536.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>