Mssql 2012 - найдите строки, в которых столбец содержит следующие цифры

У меня есть таблица, содержащая столбец varchar(50).

Иногда в этом столбце встречаются недопустимые значения. Сейчас я его чищу и много хорошо поработал, используя regex и string manipulation functions.

Теперь я застрял с такими значениями: 123456789 или 5678 или 987654.

Как я могу получить все строки, содержащие цифры в этом столбце, в порядке возрастания или убывания?

Их не так уж и много. Я бы просто создал их все.

paparazzo 11.04.2018 12:07

Нет другого пути, кроме как перечислить их like (1|12|123)

Jay Shankar Gupta 11.04.2018 12:14
2
2
63
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

How can I retrieve all the rows that this column contains digits in a going up or down order?

Для этого вы можете попробовать что-то вроде:

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

Скрипка

Примечание: ISNUMERIC не идеален. Он также будет рассматривать некоторые символы как числовые. Вы можете прочитать это здесь

Работает, пока вы не получите такие значения, как '.' и '$' и т. Д. SELECT ISNUMERIC('.'), ISNUMERIC('$') возвращает 1 для обоих значений.

Larnu 11.04.2018 12:18

@Larnu, Ага, добавил в свой ответ.

an33sh 11.04.2018 12:23

Не работает. Вернуло 12456. цифра 3 отсутствует

Itay.B 11.04.2018 13:13

Может, как-то так ...? Однако это полностью непроверено:

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) + '%';

Вы можете просто сгенерировать последовательности

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;

Вы можете использовать функции мода. Сначала нужно убедиться, что все ваши значения числовые.

-- 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)
        )
    )
Ответ принят как подходящий

Я нашел хорошее простое решение. Вдохновленный ответом @Larnu.

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

ОБЪЯВЛЕНИЕ @RevPattern varchar (9) = '987654321';

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

Другие вопросы по теме