MSSQL 2012 - 查找列包含以下数字的行

时间:2018-04-11 10:02:51

标签: sql sql-server

我有一个包含varchar(50)列的表格。

有时此列中存在无效值。我现在正在清理它并使用regexstring manipulation functions做了很多好工作。

我现在遇到这样的价值观: 123456789 5678 987654

如何按上或下顺序检索此列包含数字的所有行?

5 个答案:

答案 0 :(得分:3)

  

如何检索此列包含数字的所有行   上下订单?

为此,您可以尝试类似的事情,

select * from my_table
where isnumeric(my_column) = 1
order by CAST(my_column AS int);

Fiddle

注意:ISNUMERIC并不完美。它会将某些字符视为数字。你可以阅读它here

答案 1 :(得分:1)

也许是这样的......?但它完全未经测试:

DECLARE @Run varchar(9) = '123456789';

WITH Nums AS (
    SELECT 1 AS i
    UNION ALL
    SELECT i + 1
    FROM Nums
    WHERE i + 1 <= 9),
Ranges AS (
    SELECT SUBSTRING(@Run, N1.I, N2.I) AS Run
    FROM Nums N1
         JOIN Nums N2 ON N2.I >= 4
                     AND N1.I + N2.I <= 10)
SELECT *
FROM YourTable YT
     CROSS JOIN Ranges R --yes, I know this turns into an implicit JOIN 
                         --I just felt it was easier to display by using the WHERE
WHERE YT.YourColumn LIKE '%' + R.Run + '%'
   OR YT.YourColumn LIKE '%' + REVERSE(R.Run) + '%';

答案 2 :(得分:0)

您可以使用只生成序列

with cte as 
( select i, i as nxt, i as num 
  from (values (1), (2), (3), (4), (5), (6), (7), (8), (9)) v(i)
  union all 
  select i, nxt + 1, num * 10 + nxt + 1 from cte  
  where nxt + 1 <= 9
)
select * from cte 
order by i, nxt;

with cte as 
( select i, i as nxt, cast(i as bigint) as num 
  from (values (1), (2), (3), (4), (5), (6), (7), (8), (9)) v(i)
  union all 
  select i, nxt - 1, num * 10 + nxt-1
  from cte  
  where nxt - 1 >= 0
)
select * from cte 
order by i, nxt desc;

答案 3 :(得分:0)

您可以使用Mod功能。需要确保所有值都是数字的。

-- Mod calculation example
DECLARE @Number VARCHAR(100) = '123468'

SELECT
    Original = @Number,
    Length = LEN(@Number),
    Mod1 = CASE WHEN LEN(@Number) >= 1 THEN @Number / 1 % 10 END,
    Mod2 = CASE WHEN LEN(@Number) >= 2 THEN @Number / 10 % 10 END,
    Mod3 = CASE WHEN LEN(@Number) >= 3 THEN @Number / 100 % 10 END,
    Mod4 = CASE WHEN LEN(@Number) >= 4 THEN @Number / 1000 % 10 END,
    Mod5 = CASE WHEN LEN(@Number) >= 5 THEN @Number / 100000 % 10 END,
    Mod6 = CASE WHEN LEN(@Number) >= 6 THEN @Number / 1000000 % 10 END,
    Mod7 = CASE WHEN LEN(@Number) >= 7 THEN @Number / 10000000 % 10 END,
    Mod8 = CASE WHEN LEN(@Number) >= 8 THEN @Number / 100000000 % 10 END


-- Table example
IF OBJECT_ID('tempdb..#Numbers') IS NOT NULL
    DROP TABLE #Numbers

CREATE TABLE #Numbers (numberString VARCHAR(100))

INSERT INTO #Numbers (numberString)
VALUES
    ('123456789'),
    ('915'),
    ('015463'),
    ('3468'),
    ('7654'),
    ('3210')


;WITH ModCalculations AS
(
    SELECT
        Original = numberString,
        Length = LEN(numberString),
        Mod1 = CASE WHEN LEN(numberString) >= 1 THEN numberString / 1 % 10 END,
        Mod2 = CASE WHEN LEN(numberString) >= 2 THEN numberString / 10 % 10 END,
        Mod3 = CASE WHEN LEN(numberString) >= 3 THEN numberString / 100 % 10 END,
        Mod4 = CASE WHEN LEN(numberString) >= 4 THEN numberString / 1000 % 10 END,
        Mod5 = CASE WHEN LEN(numberString) >= 5 THEN numberString / 100000 % 10 END,
        Mod6 = CASE WHEN LEN(numberString) >= 6 THEN numberString / 1000000 % 10 END,
        Mod7 = CASE WHEN LEN(numberString) >= 7 THEN numberString / 10000000 % 10 END,
        Mod8 = CASE WHEN LEN(numberString) >= 8 THEN numberString / 100000000 % 10 END
    FROM
        #Numbers AS T
)
SELECT
    *
FROM
    ModCalculations AS T
WHERE
    (
        (
            T.Mod1 + 1 = T.Mod2 AND
            T.Mod2 + 1 = T.Mod3 AND
            T.Mod3 + 1 = T.Mod4 AND
            (T.Mod4 + 1 = T.Mod5 OR T.Mod4 * T.Mod5 IS NULL) AND
            (T.Mod5 + 1 = T.Mod6 OR T.Mod5 * T.Mod6 IS NULL) AND
            (T.Mod6 + 1 = T.Mod7 OR T.Mod6 * T.Mod7 IS NULL) AND
            (T.Mod7 + 1 = T.Mod8 OR T.Mod7 * T.Mod8 IS NULL)
        )
        OR
        (
            T.Mod1 - 1 = T.Mod2 AND
            T.Mod2 - 1 = T.Mod3 AND
            T.Mod3 - 1 = T.Mod4 AND
            (T.Mod4 - 1 = T.Mod5 OR T.Mod4 * T.Mod5 IS NULL) AND
            (T.Mod5 - 1 = T.Mod6 OR T.Mod5 * T.Mod6 IS NULL) AND
            (T.Mod6 - 1 = T.Mod7 OR T.Mod6 * T.Mod7 IS NULL) AND
            (T.Mod7 - 1 = T.Mod8 OR T.Mod7 * T.Mod8 IS NULL)
        )
    )

答案 4 :(得分:0)

我找到了一个很好的简单解决方案。灵感来自@Larnu的答案。

DECLARE @Pattern varchar(9) = '123456789';

DECLARE @RevPattern varchar(9)=&#39; 987654321&#39;;

SELECT *
FROM table_1 YT     
WHERE charINDEX(YT.col1, @Pattern) > 0
   or charINDEX(YT.col1, @RevPattern) > 0