Sql 如何查找列中是否有重复的数字
我的数据库是SQL Server。我有一个电话号码字段。如果电话号码包含重复7次以上的相同数字,我必须返回无效值?例如(401)2510897-->有效。(401)444-->无效。强烈建议将此要求纳入程序中,以处理或使用clr。如果必须使用t-sql,可以这样做:Sql 如何查找列中是否有重复的数字,sql,sql-server,Sql,Sql Server,我的数据库是SQL Server。我有一个电话号码字段。如果电话号码包含重复7次以上的相同数字,我必须返回无效值?例如(401)2510897-->有效。(401)444-->无效。强烈建议将此要求纳入程序中,以处理或使用clr。如果必须使用t-sql,可以这样做: -- Auxiliary function, this function is very commonly used and can be left in the database CREATE FUNCTION [dbo].[Sp
-- Auxiliary function, this function is very commonly used and can be left in the database
CREATE FUNCTION [dbo].[SplitByTrunk](@str varchar(max), @len int = 1)
RETURNS TABLE
AS
RETURN
(
with c0 as(
select @str as s
), c1 as(
select number+1 as n from master.dbo.spt_values where type = 'P' and number >= 0 and number%@len = 0
)
select ROW_NUMBER() over(order by c1.n) as pos
, SUBSTRING(c0.s, c1.n, @len) as item
from c0
inner join c1 on c1.n <= LEN(c0.s)
)
-- Then
create table #temp(num varchar(32))
insert into #temp(num) values('(401) 2510897'), ('(401) 4444444')
select num
, (case when (select MAX(cnt)
from(select COUNT(*) as cnt from [dbo].[SplitByTrunk](num, 1) group by item) as d) < 7
then 'Valid.'
else 'Invalid.'
end) as isvalid
from #temp
好像是在做这个工作
SELECT
Telephone,
CASE
WHEN Telephone LIKE '%0%0%0%0%0%0%0%' THEN 'Invalid'
WHEN Telephone LIKE '%1%1%1%1%1%1%1%' THEN 'Invalid'
WHEN Telephone LIKE '%2%2%2%2%2%2%2%' THEN 'Invalid'
WHEN Telephone LIKE '%3%3%3%3%3%3%3%' THEN 'Invalid'
WHEN Telephone LIKE '%4%4%4%4%4%4%4%' THEN 'Invalid'
WHEN Telephone LIKE '%5%5%5%5%5%5%5%' THEN 'Invalid'
WHEN Telephone LIKE '%6%6%6%6%6%6%6%' THEN 'Invalid'
WHEN Telephone LIKE '%7%7%7%7%7%7%7%' THEN 'Invalid'
WHEN Telephone LIKE '%8%8%8%8%8%8%8%' THEN 'Invalid'
WHEN Telephone LIKE '%9%9%9%9%9%9%9%' THEN 'Invalid'
ELSE 'Valid'
END
FROM
MyTable
或者使用复制使其更清晰必须少于7个匹配项
SELECT
Telephone,
CASE
WHEN Telephone LIKE '%' + REPLICATE('0%', 7) THEN 'Invalid'
WHEN Telephone LIKE '%' + REPLICATE('1%', 7) THEN 'Invalid'
WHEN Telephone LIKE '%' + REPLICATE('2%', 7) THEN 'Invalid'
WHEN Telephone LIKE '%' + REPLICATE('3%', 7) THEN 'Invalid'
WHEN Telephone LIKE '%' + REPLICATE('4%', 7) THEN 'Invalid'
WHEN Telephone LIKE '%' + REPLICATE('5%', 7) THEN 'Invalid'
WHEN Telephone LIKE '%' + REPLICATE('6%', 7) THEN 'Invalid'
WHEN Telephone LIKE '%' + REPLICATE('7%', 7) THEN 'Invalid'
WHEN Telephone LIKE '%' + REPLICATE('8%', 7) THEN 'Invalid'
WHEN Telephone LIKE '%' + REPLICATE('9%', 7) THEN 'Invalid'
ELSE 'Valid'
END
FROM
MyTable
您可以通过使用一些窗口函数和递归cte来解决这个问题,但是-取决于记录的数量-我想性能不会那么好:
DECLARE @t TABLE(
TelID int,
TelNo VARCHAR(50)
)
INSERT INTO @t VALUES
(1, '(401) 4444444')
,(2, '(401) 4444344')
;WITH cteTelPos AS(
SELECT TelID, TelNo, 1 id, LEFT(TelNo, 1) AS TelPos, RIGHT(TelNo, LEN(TelNo)-1) AS tel
FROM @t
UNION ALL
SELECT TelID, TelNo, id+1, LEFT(tel, 1), RIGHT(tel, LEN(tel)-1)
FROM cteTelPos
WHERE LEN(tel) >= 1
),
cteFilterGrp AS(
SELECT TelID, TelNo, id, TelPos
,(id - DENSE_RANK() OVER (PARTITION BY TelPos ORDER BY id)) * RANK() OVER (ORDER BY TelPos) AS grp
FROM cteTelPos
),
cteInval AS(
SELECT TelID, TelNo, TelPos, Grp, COUNT(*) cnt
FROM cteFilterGrp
GROUP BY TelID, TelNo, TelPos, Grp
HAVING COUNT(*) >= 7
),
cteInvalSrt AS(
SELECT TelID, TelNo, TelPos, Grp, cnt, ROW_NUMBER() OVER (ORDER BY cnt DESC) AS rn
FROM cteInval
)
SELECT t.*, CASE WHEN s.cnt IS NULL THEN N'Valid' ELSE N'Invalid' END AS TelStatus
FROM @t AS t
LEFT JOIN cteInvalSrt s ON s.TelID = t.TelID AND s.rn = 1
不确定,但我认为您需要这里的
\1
regex,我认为MSSQL不支持它:/下面的答案之一提供了解决方案吗?如果是这样,请考虑接受它。唯一的问题是“超过7”实际上意味着代码>8 < /代码>。我还应该指出,如果“超过7次”真的意味着连续超过7次,那么这很容易调整。
DECLARE @t TABLE(
TelID int,
TelNo VARCHAR(50)
)
INSERT INTO @t VALUES
(1, '(401) 4444444')
,(2, '(401) 4444344')
;WITH cteTelPos AS(
SELECT TelID, TelNo, 1 id, LEFT(TelNo, 1) AS TelPos, RIGHT(TelNo, LEN(TelNo)-1) AS tel
FROM @t
UNION ALL
SELECT TelID, TelNo, id+1, LEFT(tel, 1), RIGHT(tel, LEN(tel)-1)
FROM cteTelPos
WHERE LEN(tel) >= 1
),
cteFilterGrp AS(
SELECT TelID, TelNo, id, TelPos
,(id - DENSE_RANK() OVER (PARTITION BY TelPos ORDER BY id)) * RANK() OVER (ORDER BY TelPos) AS grp
FROM cteTelPos
),
cteInval AS(
SELECT TelID, TelNo, TelPos, Grp, COUNT(*) cnt
FROM cteFilterGrp
GROUP BY TelID, TelNo, TelPos, Grp
HAVING COUNT(*) >= 7
),
cteInvalSrt AS(
SELECT TelID, TelNo, TelPos, Grp, cnt, ROW_NUMBER() OVER (ORDER BY cnt DESC) AS rn
FROM cteInval
)
SELECT t.*, CASE WHEN s.cnt IS NULL THEN N'Valid' ELSE N'Invalid' END AS TelStatus
FROM @t AS t
LEFT JOIN cteInvalSrt s ON s.TelID = t.TelID AND s.rn = 1