Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何查找列中是否有重复的数字_Sql_Sql Server - Fatal编程技术网

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

我的数据库是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].[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