iT邦幫忙

0

oracle sql select 諮詢

  • 分享至 

  • xImage

大家好
我想要諮詢如何在一個select可以達到這個表格的結果?
其中"select result"的結果可以透過select達成,但是我必須建立"need create"的資料行。
serno我通常會使用sequence的物件取號,但是1~999的循環中必須保持同一個serno,下一個循環再取新。
rownum則是取1~999的循環,非常感謝!!!
https://ithelp.ithome.com.tw/upload/images/20220212/20146507k4nmsSyV0H.png

我自己的做法比較老土,我弄了一個view的結果會長的像"need create"的資料,再跟"select result"join起來,可是有個缺點是我的view資料列的數量沒辦法隨著"select result"變化。

看更多先前的討論...收起先前的討論...
你的描述, 我個人是覺得有疑問. 不知道你要的是
(a) serno 跳號時, rownum 就 reset 到 1, 從新開始,不論 rownum 跳到哪號.
或是
(b) rownum 是從 1~999 ,然後warp 回到 1 , 不管 serno.
z1dane iT邦新手 5 級 ‧ 2022-02-13 00:57:39 檢舉
其實就是取一次的serno,rownum就從1取到999 ,999的下一號不能是1000 ,又得重新取一個serno,然後rownum又從1取到999,不斷循環
z1dane iT邦新手 5 級 ‧ 2022-02-13 01:00:42 檢舉
如果資料只有500筆 那serno都會是同一個 rownum就是1~500
如果資料有3000筆 那serno總共會取四次
每次新的serno的rownum都會回到1沒錯
所以你的情境是 (b), 然後 serno 是跟著 rownum 跳 ?
z1dane iT邦新手 5 級 ‧ 2022-02-13 01:04:48 檢舉
目前取serno的機制是一個function裡面會去select XXX_seq.nextval from dual
如果我直接放在select這個function出來的結果每個資料列都是一個新的serno
z1dane iT邦新手 5 級 ‧ 2022-02-13 01:06:31 檢舉
是B 算是跟著rownum跳沒錯 我範例欄位名稱取的不好 rownum是語法 有點混淆 不好意思
@一級屠豬士大大

> 所以你的情境是 (b), 然後 serno 是跟著 rownum 跳 ?

其實他只是「自動加編號」,只是編號是「兩階式」而已
serno 用另一個 function/sequence 取得
rownum 則是由 1~999, 之後從 1 開始
@一級屠豬士大大

就算這個需求做出來了,代表
每次 SELECT 出來的「結果」(serno) 都會不一樣
我真的想不懂怎麼會有這種需求

可能是自己見識淺薄吧 -_-|||
z1dane iT邦新手 5 級 ‧ 2022-02-13 09:48:18 檢舉
因為業務上有這種需求= =,如同海綿寶寶所說,每次select的serno都會不一樣沒錯,因下一流程沒辦法接收重複的serno+rownum組合,而serno每次取新效能又會不好
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

1
一級屠豬士
iT邦大師 1 級 ‧ 2022-02-13 11:07:24
最佳解答

https://dbfiddle.uk/?rdbms=oracle_21&fiddle=432d5dc83096481a4a940a84f2a7298e

上面的測試版本.概略說明一下,因為這個測試用的,有些功能受到限制,我原本要用亂數產生,但是
受到限制,所以就改用一堆 insert.
999 我改為9 , 這樣來模擬.
至於裡面的測試table,你應該會改成你查詢的 result. 不過你沒有排序順序, 所以我就自己用
了 row_number() over() 來產生序號來讓後面的 join 能做.
另外那個 rownum 是保留字, 所以改為 xrn.

z1dane iT邦新手 5 級 ‧ 2022-02-13 14:18:29 檢舉

目前我加工了一下,可以運行,但是有個地方怪怪的我還在想
with t1 as (
select rownum rn, t.* from (select * from [mytable] where [mycol] < 1000049753 order by [mycol]) t
),
t2 (cnt, i, j) as (
select 1 , 1 , 1
from dual
union all
select cnt + 1
, case
when mod(i, 9) = 0 then 1
else i + 1
end
, case
when mod(i, 9) = 0 then j + 1
else j
end
from t2
where cnt < (select count(1) from t1)
),
t3 as (
select j, [fn_mysequence] serno from t2 group by j order by j
)
select t3.serno
, t2.cnt, t2.i, t2.j
, t1.*
from t1, t2, t3
where t2.cnt = t1.rn and t2.j=t3.j
order by t1.rn
;

我這樣select出來 我發現我取的serno會沒辦法照順序跳號
https://ithelp.ithome.com.tw/upload/images/20220213/201465070mhb7xxgSy.png
但是這個select的結果insert到我的記錄表serno的順序就會正常了
就是看起來是order by serno, i

你沒有指定 order by 順序的話, 每次查詢的順序是不一定的,連帶
rownum 這個虛擬欄位也是會變化的,他是依照查詢的結果賦予的.
所以你查詢的結果,應該設法都查完後, 一次性的排序,看是要用 rownum,或是 row_number() over() 來取得流水號.
可以採用 喵凹咿唉思嗯 大大的範例裡的運算式,那樣會更簡潔有力.

z1dane iT邦新手 5 級 ‧ 2022-02-13 15:50:41 檢舉

了解謝謝 我又試了一下 最後改成這樣打算先交差

with t1 as (
select * from [mytable] where [mycol] < 1000049753 order by [mycol]
),
t2 (cnt, i, j) as (
select 1 , 1 , 1
from dual
union all
select cnt + 1
, case
when mod(i, 9) = 0 then 1
else i + 1
end
, case
when mod(i, 9) = 0 then j + 1
else j
end
from t2
where cnt < (select count(1)+1 from t1)
),
t3 as (
select j, [myfunction] serno from t2 group by j order by j
)
select
t3.serno, t2., u1.
from (select rownum rn, t.* from t1 t) u1
join t2 on u1.rn = t2.cnt
join t3 on t2.j = t3.j
--order by t2.cnt 不能加這行
;

這樣順序目前看起來是沒亂跳
感謝各路大大
神演算法

1
喵凹咿唉思嗯
iT邦研究生 5 級 ‧ 2022-02-13 13:54:21

https://dbfiddle.uk/?rdbms=oracle_21&fiddle=d3c3b786fee640cd4cbc30e7a9e0b29f

如果只是單純要編號 不用考慮不同次select之間serno的話, 直接例用rownum處理就可以了

z1dane iT邦新手 5 級 ‧ 2022-02-13 14:09:48 檢舉

是一個好作法,但我目前需要去call那個公用取sequence function

我要發表回答

立即登入回答