是否可以在varchar列中进行搜索。
我得到了一个名为x的表,其中名为par的行和数据位于:
150/RXRPR1/18/0020642
150/RXRPR1/18/0020640
150/RXRPR1/18/0020639
151/RXRPR1/18/0020638
151/RXRPR1/18/0020637
151/RXRPR1/18/0020636
151/RXRPR1/18/0020634
该行丢失
150/RXRPR1/18/0020641
151/RXRPR1/18/0020635
如何编写SQL语句来搜索表以搜索丢失的数据?
数据类型为varchar
,我有权只在数据库中选择
答案 0 :(得分:2)
您可以在数字的右边7个字符中使用经典间隙检测,并按剩余的14个字符进行划分。使用LEAD函数查找下一个记录的值,并检查当前值与下一个值之间的差是否大于1。这将检测到间隙,并且可以通过将当前值加1来计算间隙的开始和结束值,然后从下一个值中减去一个。像这样:
declare @t table(col varchar(50))
insert into @t(col) values
('150/RXRPR1/18/0020642'),
('150/RXRPR1/18/0020640'),
('150/RXRPR1/18/0020639'),
('151/RXRPR1/18/0020638'),
('151/RXRPR1/18/0020637'),
('151/RXRPR1/18/0020636'),
('151/RXRPR1/18/0020634')
SELECT
gapStart = left([current], 14) + right('000000' + cast(cast(right([current], 7) as int) + 1 as varchar(10)), 7)
,gapEnd = left([next], 14) + right('000000' + cast(cast(right([next], 7) as int) - 1 as varchar(10)), 7)
FROM
(
SELECT
[current] = col
,[next] = LEAD(col) OVER (partition by left(col, 14) ORDER BY col)
FROM @t
) tmp
WHERE cast(right([next], 7) as int) - cast(Right([current], 7) as int) > 1;
答案 1 :(得分:0)
这个想法很简单。查找每个“前缀”的最小和最大数字,并与数字表结合以生成最小和最大之间的数字。寻找差距是微不足道的。请注意,如果间隙大于1,则可以使用。在642和649之间,有6个缺失值,将全部找到它们:
DECLARE @t TABLE(paragon VARCHAR(40));
INSERT INTO @t VALUES
('150/RXRPR1/18/0020642'),
('150/RXRPR1/18/0020640'),
('150/RXRPR1/18/0020639'),
('151/RXRPR1/18/0020638'),
('151/RXRPR1/18/0020637'),
('151/RXRPR1/18/0020636'),
('151/RXRPR1/18/0020634'),
('999/RXRPR1/18/0000001'),
('999/RXRPR1/18/0000010');
WITH minmax(prefix, min, max) AS (
SELECT SUBSTRING(paragon, 1, 14)
, MIN(CAST(SUBSTRING(paragon, 15, 7) AS INT))
, MAX(CAST(SUBSTRING(paragon, 15, 7) AS INT))
FROM @t
GROUP BY SUBSTRING(paragon, 1, 14)
), numbers AS (
SELECT TOP 1000 ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1 AS number
FROM sys.all_objects
), result(missing) AS (
SELECT prefix + FORMAT(min + number, '0000000')
FROM minmax
INNER JOIN numbers ON number <= (max - min)
LEFT JOIN @t AS t ON prefix + FORMAT(min + number, '0000000') = paragon
WHERE paragon IS NULL
)
SELECT *
FROM result
答案 2 :(得分:0)
您可以尝试以下查询:
请用相应的值替换@ MINVAL,@ MAXVAL。
declare @t table([VALUE] varchar(50))
insert into @t([VALUE]) values
('150/RXRPR1/18/0020642'),
('150/RXRPR1/18/0020640'),
('150/RXRPR1/18/0020639'),
('151/RXRPR1/18/0020638'),
('151/RXRPR1/18/0020637'),
('151/RXRPR1/18/0020636'),
('151/RXRPR1/18/0020634')
DECLARE @MINVAL INT = 20634,
@MAXVAL INT = 20642;
WITH cte
AS (SELECT @MINVAL VAL
UNION ALL
SELECT val + 1 VAL
FROM cte
WHERE val < @MAXVAL)
SELECT missing
FROM (SELECT *,
Replace (Lead([VALUE]) OVER ( ORDER BY val)
, CONVERT (INT, RIGHT (Lead([VALUE]) OVER (ORDER BY val), 7)),
val)
MISSING
FROM cte
LEFT JOIN @t X
ON CONVERT (INT, RIGHT (X.[VALUE], 7)) = cte.val) X
WHERE [VALUE] IS NULL OPTION ( MAXRECURSION 10000)