我在SQL Server中有一个表,需要在其中按名称和类型过滤房间。问题是,名称存储为varchar
,并且还有一些带有字母的房间。我需要先用字母过滤掉房间,然后才能将它们与int
进行比较,否则我将得到一个错误。
以下是Room.Name的示例:
030
210a
210b
Lan-Room-A
240
我可以使用a
或b
和LEFT(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子句之前包含字符串的行,但是我不知道如何。
你们有什么主意吗?
请注意,我无法编辑数据库。
谢谢。
答案 0 :(得分:2)
您可以使用TRY_CAST
:
SELECT *
FROM Rooms
WHERE TRY_CAST(LEFT(Rooms.Name, 3) AS INT) BETWEEN 0 and 350;
即使正确检查,也不能保证您的第二种方法会起作用:
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
这行得通,因为您将数字用零填充,因此可以进行字符串比较。