SQL 过滤 x 和 x 之间的数字并忽略字符串
SQL Filter numbers between x and x and ignore strings
我在 SQL 服务器中有一个 table,我需要在其中按名称和类型过滤房间。问题是,名称存储为 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 子句之前包含字符串的行,但我不知道该怎么做。
你们有什么想法吗?
请注意,我无法编辑数据库。
提前致谢。
您可以使用 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
可能会产生转换错误。
对于 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)
我不明白这个问题。您可以使用字符串:
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
这是可行的,因为您对数字进行了零填充,因此字符串比较将起作用。
我在 SQL 服务器中有一个 table,我需要在其中按名称和类型过滤房间。问题是,名称存储为 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 子句之前包含字符串的行,但我不知道该怎么做。
你们有什么想法吗?
请注意,我无法编辑数据库。
提前致谢。
您可以使用 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
可能会产生转换错误。
对于 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)
我不明白这个问题。您可以使用字符串:
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
这是可行的,因为您对数字进行了零填充,因此字符串比较将起作用。