本範例將查詢具有相同數字之數值(如:1、11、22或888等),主要撰寫概念是以每個數值第一個數字(即最大位數)為除數,除以整個數值,若商數均為數字1、如1、11、111…等,即代表此數值每個數字相同。MSSQL及ORACLE均應用相同概念撰寫,SQL及結果如下:
SQL
|
||
MSSQL
|
SELECT D.VAL
, N.Num
, D.VAL / N.Num Quotient --重點2.{數值}除以{數值}第1碼之{數字}得到商數,均為1者即為所求
, PATINDEX('%[^1]%',CAST((D.VAL/N.Num) AS varchar)) Pos --重點3.商數第1個數字不為1之位置
FROM
(--產生{1~9}數值數列,取自master.dbo.spt_values
SELECT CAST(number AS VARCHAR) Num
FROM master.dbo.spt_values
WHERE name IS NULL
AND number
BETWEEN 1 AND
9
) N
WHERE 1=1
AND D.VAL LIKE N.Num + '%' --重點1.以{數值第1碼}與{數字1~9}進行Table Join
--AND PATINDEX('%[^1]%',
CAST((D.VAL / N.Num)
AS VARCHAR)) = 0
ORDER BY N.NUM, D.VAL
註: VAULES為2008功能,先前文章以介紹,請自行參考不贅述。
|
|
ORACLE
|
SELECT D.Val
, N.Num
, TRUNC(D.VAL/N.Num) Quotient --重點2.{數值}除以{數值}第1碼之{數字}得到商數,均為1者即為所求
, REGEXP_INSTR(TRUNC(D.VAL/N.Num), '[^1]') Pos --重點3.商數第1個數字不為1之位置
FROM
(--產生{1~9}數值數列,以CONNECT BY產生
SELECT LEVEL
Num
FROM DUAL
CONNECT BY
LEVEL <=9
) N
WHERE 1=1
AND D.VAL LIKE N.Num ||'%' --重點1.以{數值第1碼}與{數字1~9}進行Table Join
--AND
REGEXP_INSTR(TRUNC(D.VAL/N.Num),
'[^1]') = 0
ORDER BY N.NUM, D.VAL
註: Split_tbl為自訂type配合table函數,可將CSV字串轉為Table,後續文章再行介紹。
|
註:虛線段落如無法瞭解,可自行CREATE TABLE / INSERT TABLE建立測試資料。
重點1: 以Join方式得到數值第一個數字。
重點3: 以Regular Expression找出商數中第一個非為1之位置,如均為1則回傳為0,MSSQL可應用PATINDEX函數;ORACLE則可使用REGEXP_INSTR,可參閱拙著或後續文章將說明。
執行結果
|
說明
|
|
欄位說明
ü VAL: 數值
ü NUM: 數值第1碼數字
ü Quotient: VAL除以NUM之商數
ü Pos:不為1之數字位置,0代表均為1。
|
沒有留言:
張貼留言