簡體   English   中英

SQL獲取電話號碼序列

[英]SQL to get sequence of phone numbers

我有一個名為PhoneNumbers的表,其中包含Phone和Range列,如下所示

在此處輸入圖片說明

在“電話”列中,我有一個電話號碼,在“范圍”列中,我有一個值范圍,我需要包含這些電話號碼。對於第一個電話號碼9125678463,我需要包含電話號碼,直到范圍9125678465,即(9125678463, 9125678464,9125678465)。同樣也適用於其他電話號碼。此處的示例目標表應類似於

在此處輸入圖片說明

我怎么寫SQL來得到這個?

提前致謝

您可以像這樣使用CTE:

;WITH CTE (PhoneNumbers, [Range], i) AS (
    SELECT CAST(Phone AS bigint), [Range], CAST(1 AS bigint)
    FROM yourTable
    UNION ALL
    SELECT CAST(PhoneNumbers + 1 AS bigint), [Range], i + 1
    FROM CTE
    WHERE (PhoneNumbers + 1) % 10000 <= [Range] 
)
SELECT PhoneNumbers
FROM CTE
ORDER BY PhoneNumbers

這是使用理貨表格的一個示例。 在我的系統中,我將這套ctes作為視圖,因此不必再編寫它。

if OBJECT_ID('tempdb..#PhoneNumbers') is not null
    drop table #PhoneNumbers;

create table #PhoneNumbers
(
    Phone char(10)
    , Range smallint
) 

insert #PhoneNumbers
    select 9135678463, 8465 union all
    select 3279275678, 5679 union all
    select 6372938103, 8105;

WITH
E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS 
(
    SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)

select *
from #PhoneNumbers p
join cteTally t on t.N >= RIGHT(Phone, 4) and t.N <= Range
order by p.Phone

我有一個解決方案,但采用了經典的方式:但是它不需要遞歸,也不需要任何循環! 即使您的范圍長度為3或5,或任何其他值,它也能正常工作...

首先,我創建一個帶有數字的表(在此示例中為1到1百萬-您可以在TOP()子句中采用此表):

SELECT TOP (1000000) n = CONVERT(INT, ROW_NUMBER() OVER (ORDER BY s1.[object_id]))
INTO dbo.Numbers
FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2
OPTION (MAXDOP 1);

CREATE UNIQUE CLUSTERED INDEX idx_numbers ON dbo.Numbers(n)
;

如果您有該表,則非常簡單:

;WITH phonenumbers
AS
(
SELECT  phone,
        [range],
        CAST(RIGHT(phone,LEN([range])) AS INT) AS number_to_increase,
        CAST(LEFT(phone,LEN(phone)-LEN([range])) + REPLICATE('0',LEN([range])) AS BIGINT) AS base_number
FROM    PhoneNumbers
)

SELECT  p.base_number + num.n
FROM    phonenumbers p
        INNER JOIN dbo.Numbers num ON num.n BETWEEN p.number_to_increase AND p.[range]

您不必像在這里那樣使用CTE-只是更清楚地了解這種方法的思想是什么。 也許這適合你

另一種方法:

--Creating dummy table
select '9999991234' phone, '1237' rang into #tbl
union
select '9999995689', '5692'

SELECT [phone] low
        ,(CAST(9999995689/10000 AS bigINT) * 10000  + [Rang]) high
 into #tbl1
 FROM #tbl

--Creating 'numbrs' to have numbers between 0 & 9999 i.e. max range

select (rn-1)rn
into #numbrs
from 
(select row_number() over (partition by null order by A.object_id) rn from sys.objects A 
cross join sys.objects B)A 
where rn between 0 and 9999

select (low + rn)phn from #numbrs cross join #tbl1
where (low + rn) between low and high

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM