日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

oracle子查詢分解(分而治之)

系統 2100 0
用一個sql語句完成一下問題:
??? A,B,C三人的年齡相乘為36;相加等于所有在場的人的人數;年齡大的人的寵物倉鼠的有個腿是木頭的,試著給出這三人的年齡。
??? 解決方案:
??? 需要知道用于查詢分解的基本格式,考慮類似下面的表達式
??? with
alias1 as (subQuery1)
alias2 as(subQuery2)
??????? ……
?? select
??????? ……

??? 首先,注意帶三人年齡的乘積是36,可設年齡都是整數,因此就必須創建一個1~36的范圍內,——就需要一個36行的表,每一個表對應一個可能的年齡:
??? with age_list as
??? {
??? select rowNum as age from dual where rowNum<=36;
??? },
???? 是三個人,需要創建三個副本,同時年齡乘積是36——之后還要把這3個年齡相加,下面同時進行。注意前面的SQL結尾使用是一個逗號,下面的部分就簡單地以一個新的別名開始(不再重復with):
???? product_check as
????? {
?????????? select
????????????????????? age1.age as youngest,
????????????????????? age2.age as middle,
????????????????????? age3.age as oldest
????????????????????? age1.age+age2.age+age3.age as sumed
?????????? from age_list age1,age_list2 age2,age_list age3
?????????? where age1.age<=age2.age and age2.age<=age3.age?? //保證每種組合值出現一次
????????????????????? and age1.age*age2.age*age3.age=36
???? }
??? 得出的結果是
??? Y???????????? M????????? O??????????? S
——————————————————————————
??? 1????????????? 1?????????? 36?????????? 38
??? 1????????????? 2?????????? 18?????????? 21
??? 1????????????? 3?????????? 12?????????? 16
??? 1????????????? 4???????? ?? 9???????????? 14
??? 1????????????? 6????????? 6???????????? 13
??? 2????????????? 2??????????? 9???????????? 13
??? 2????????????? 3??????????? 6???????????? 11
??? 3????????????? 3?????? ?? 4 10 ???
?? 現在 年齡之和等于一個數,知道了現場人數仍不能確定,——說明查詢集合的和至少有兩行的值是一樣的。
?? 縮小輸出范圍
??? summed_checked as
???? {
?????????? select youngest, middle, oldest ,sumed
?????????? from
??????????????? { select youngest,middle,oldest,sumed,count (*) over (partition by summed) cnt
??????????????????? from???? product_chect
??????????????? }
?????????? where cnt>=2
?? }
?? 輸出結果:
??? Y????????????? M????????????? O????????????? S
————————————————————————————
??? 1????????????? 6????????????? 6????????????? 13
??? 2????????????? 2????????????? 9????????????? 13
??? 接著“年齡大的人的寵物倉鼠有個腿是木質的”,表明年齡大的人的年齡比中間那個要大。
??? 所以
??? select yongest,middle,oldest from sumed_checked
where oldest>middle
??? 得出結果:
??? Y????????????? M????????????? O????????????? S
————————————————————————————
??? 2????????????? 2????????????? 9????????????? 13
??

完整的查詢如下(在oracle9.2.0.1中測試通過):
with
age_list as
?? (select rowNum age from all_all_tables where rownum<=36),
product_check as
(
??? select
?????? age1.age youngest,
?????? age2.age middle,
?????? age3.age oldest,
?????? age1.age+age2.age+age3.age as sumed
??? from age_list age1,age_list age2,age_list age3
??? where age1.age<=age2.age and age2.age<=age3.age
??? and age1.age*age2.age*age3.age=36
),
sumed_check as
(
?? select youngest,middle,oldest,sumed
?? from
????? (
????????? select youngest,
???????????????? middle,
???????????????? oldest,
???????????????? sumed,
???????????????? count(*) over(partition by sumed) cnt
????????? from product_check???????????????
????? )
?? where cnt>=2??
)
select youngest,middle,oldest
from sumed_check
where middle<oldest

----------------------------------------------------------------
oracle 中with的用法
????? 當查詢中多次用到某一部分時,可以用with語句創建一個公共臨時表。因為子查詢在內存臨時表中,避免了重復解析,所以執行效率會提高不少。臨時表在一次查詢結束自動清除。
?????? 一般語法格式:
?????? with
alias_name1 as??? (subquery1),
??????????? alias_name2 as??? (subQuery2),
??????????? ……
??????????? alias_nameN as??? (subQueryN)
????? select col1,col2…… col3
???????????????? from alias_name1,alias_name2……,alias_nameN

????? 例子:
????? SQL> WITH
Q1 AS (SELECT 3 + 5 S FROM DUAL),
??????????????? Q2 AS (SELECT 3 * 5 M FROM DUAL),
??????????????? Q3 AS (SELECT S, M, S + M, S * M FROM Q1, Q2)
SELECT * FROM Q3;
輸出結果:
S M S+M S*M
---------- ---------- ---------- ----------
8 15 23 120

???? 所有的子查詢都可以用到,下面是轉帖網上的一個UPDATE語句(url:http://www.oracle.com.cn/viewthread.php?tid=83530):(

在討論一個有關表的UPDATE時, 寫了如下的SQL:<原始需求,請參考: http://www.oracle.com.cn/viewthr ... ghlight=&page=2 >

SQL> update test2 set spc = (
?? 2 ?? ?? select substr(max(sys_connect_by_path(b.name, '-')),2) name
?? 3 ?? ?? ?? from (select rn, skycode id,
?? 4 ?? ?? ?? ?? ?? ?? ?? ??? decode(rn, 1, 0, instr(skycode, '-', 1, rn-1)) + 1 sp,
?? 5 ?? ?? ?? ?? ?? ?? ?? ??? decode(instr(skycode, '-', 1, rn), 0, length(skycode) + 1, instr(skycode, '-', 1, rn)) ep
?? 6 ?? ?? ?? ?? ?? ?? from (select rownum rn from dual connect by rownum<=20) a, test2 b
?? 7 ?? ?? ?? ?? ?? ?? where decode(rn, 1, 0, instr(skycode, '-', 1, rn-1)) + instr(skycode, '-', 1, rn) > 0
?? 8 ?? ?? ?? ?? ?? ) a, test b
?? 9 ?? ?? ?? where b.citycode = substr(a.id, sp, ep-sp) and a.id=test2.skycode
10 ?? ?? ?? start with rn=1 connect by rn-1=prior rn and a.id = prior a.id );

當時是在9.2.0.7下做的,沒有問題,可以有朋友在9.2.0.1下,就會出現:

ORA-03113:通信通道文件結束
ORA-03114:未連接ORACLE

的錯誤提示, 這是9.2.0.1的一個BUG, 在多次的子查詢時出現, 我試過,在9.2.0.5已經沒有了,但不知道從那個版本ORACLE做了更正.

前段時間在寫類似的多子查詢的SELECT語句時, ORACLE9I提供的一個新子句: WITH在某種程度上解決了部分這類錯誤的出現. 經測試,原來同樣的寫法,也可以用于UPDATE中, 如上面的語句,可以用WITH改寫為:

SQL> update test2 set spc = (
?? 2 ?? ?? with myque as (select rn, skycode id,
?? 3 ?? ?? ?? ?? ?? ?? ?? ??? decode(rn, 1, 0, instr(skycode, '-', 1, rn-1)) + 1 sp,
?? 4 ?? ?? ?? ?? ?? ?? ?? ??? decode(instr(skycode, '-', 1, rn), 0, length(skycode) + 1,
?? 5 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? instr(skycode, '-', 1, rn)) ep
?? 6 ?? ?? ?? ?? ?? ?? ??? from (select rownum rn from dual connect by rownum<=20) a, test2 b
?? 7 ?? ?? ?? ?? ?? ?? ??? where decode(rn, 1, 0, instr(skycode, '-', 1, rn-1)) + instr(skycode, '-', 1, rn) > 0 )
?? 8 ?? ?? select substr(max(sys_connect_by_path(b.name, '-')),2) name
?? 9 ?? ?? ?? from myque a, test b
10 ?? ?? ?? where b.citycode = substr(a.id, sp, ep-sp) and a.id=test2.skycode
11 ?? ?? ?? start with rn=1 connect by rn-1=prior rn and a.id = prior a.id );

已更新4行。

可見, ORACLE在支持子查詢的地方,同時也支持WITH的操作, 本人認為,這樣一來,可以讓開發人員有更多的機會,寫出高效的單個SQL語句. 特別是在多個子查詢中多次對同一基表進行訪問時.

這是本人的更解, 不知對否, 請各位大蝦批評指正.

oracle子查詢分解(分而治之)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 陆良县| 克东县| 湖南省| 安丘市| 若尔盖县| 大宁县| 河间市| 林芝县| 永登县| 安陆市| 石首市| 邢台市| 广安市| 桐乡市| 伊宁市| 寿光市| 崇州市| 林口县| 犍为县| 吉林市| 潜江市| 新竹县| 梅河口市| 锦屏县| 平南县| 睢宁县| 河北省| 九台市| 太谷县| 大同市| 二连浩特市| 高安市| 淄博市| 全椒县| 鄂伦春自治旗| 海安县| 石渠县| 科技| 潼关县| 黄石市| 宜兴市|