SQL筛选x和x之间的数字并忽略字符串

时间:2018-06-29 09:57:35

标签: sql sql-server where

我在SQL Server中有一个表,需要在其中按名称和类型过滤房间。问题是,名称存储为varchar,并且还有一些带有字母的房间。我需要先用字母过滤掉房间,然后才能将它们与int进行比较,否则我将得到一个错误。

以下是Room.Name的示例:

030
210a
210b
Lan-Room-A
240

我可以使用abLEFT(Rooms.Name, 3)来解决房间名称,但是如果我想添加(LEFT(Rooms.Name, 3) BETWEEN 0 and 350并将其添加到Lan-Room-A无法将字符串转换为int。我还需要进行其他过滤,例如Room.Type = 6

SELECT
    Room.Name,
    Room.Descr,
    Room.MainUser
WHERE
    LEFT(Room.Name, 1) NOT LIKE '%[0-9]%' 
    AND LEFT(Room.Name, 3) BETWEEN 0 AND 350  
    AND Room.Type = 6

(为简单起见,删除了一些联接)

我只需要过滤出when子句之前包含字符串的行,但是我不知道如何。

你们有什么主意吗?

请注意,我无法编辑数据库。

谢谢。

3 个答案:

答案 0 :(得分:2)

您可以使用TRY_CAST

SELECT *
FROM Rooms
WHERE TRY_CAST(LEFT(Rooms.Name, 3) AS INT) BETWEEN 0 and 350;

DBFiddle Demo


即使正确检查,也不能保证您的第二种方法会起作用:

WHERE LEFT(Room.Name, 1) NOT LIKE '%[0-9]%' 
  AND LEFT(Room.Name, 3) BETWEEN 0 AND 350  
  and Room.Type = 6

查询优化器可以按任何顺序检查条件,因此LEFT(Room.Name, 3) BETWEEN 0 AND 350可能会产生转换错误。

答案 1 :(得分:0)

2008年。请使用它。

解决方案-

;WITH CTE AS
(
    SELECT '030' a UNION ALL
    SELECT '210a' UNION ALL
    SELECT '210b' UNION ALL
    SELECT 'Lan-Room-A' UNION ALL
    SELECT '240'
)
SELECT * FROM CTE
WHERE 
PATINDEX('%[0-9]%', a) = 1 AND
1 = CASE WHEN CAST(LEFT(a, 3) AS INT) BETWEEN 0 and 350 THEN 1 ELSE 0 END

输出

a
----------
030
210a
210b
240

(4 rows affected)

答案 2 :(得分:0)

我不明白这个问题。您可以使用字符串:

WHERE Room.Name NOT LIKE '[0-9]%' AND
      LEFT(Room.Name, 3) BETWEEN '0' AND '350' AND  
      Room.Type = 6

但是,我怀疑您的意图被捕获:

WHERE Room.Name >= '000' AND
      Room.Name < '351' AND
      Room.Type = 6

这行得通,因为您将数字用零填充,因此可以进行字符串比较。