我有一个包含varchar(50)
列的表格。
有时此列中存在无效值。我现在正在清理它并使用regex
和string manipulation functions
做了很多好工作。
我现在遇到这样的价值观: 123456789
或 5678
或 987654
如何按上或下顺序检索此列包含数字的所有行?
答案 0 :(得分:3)
如何检索此列包含数字的所有行 上下订单?
为此,您可以尝试类似的事情,
select * from my_table
where isnumeric(my_column) = 1
order by CAST(my_column AS int);
注意: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