Reputation: 23
I have a table in SQL Server where I need to filter rooms by name and type. The problem is, that the names are stored as varchar
and there are also some rooms with letters. I need to filter out the rooms with letters before I can compare them as int
or otherwhise I will get an error.
Here's an example from Room.Name:
030
210a
210b
Lan-Room-A
240
I can work around the room names with a
or b
with LEFT(Rooms.Name, 3)
but if I want to add (LEFT(Rooms.Name, 3) BETWEEN 0 and 350
and it gets to Lan-Room-A
it oviously can't convert a string to int. I also need to do additional filtering like Room.Type = 6
for example.
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
(Removed some joins for simplicity)
I simply need to filter out the rows which contain strings before the when clause, but I have no idea how.
Do you guys have any idea?
Please note that I can't edit the database.
Thanks in advance.
Upvotes: 2
Views: 2607
Reputation: 1269923
I don't understand the issue. You can use strings:
WHERE Room.Name NOT LIKE '[0-9]%' AND
LEFT(Room.Name, 3) BETWEEN '0' AND '350' AND
Room.Type = 6
However, I suspect your intention is captured by:
WHERE Room.Name >= '000' AND
Room.Name < '351' AND
Room.Type = 6
This works because you have zero-padded the numbers, so string comparisons will work.
Upvotes: 0
Reputation: 2021
For 2008. Please use this.
Solution-
;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
OUTPUT
a
----------
030
210a
210b
240
(4 rows affected)
Upvotes: 0
Reputation: 175736
You could use TRY_CAST
:
SELECT *
FROM Rooms
WHERE TRY_CAST(LEFT(Rooms.Name, 3) AS INT) BETWEEN 0 and 350;
Your second approach is not guaranteed to work even with correct check:
WHERE LEFT(Room.Name, 1) NOT LIKE '%[0-9]%'
AND LEFT(Room.Name, 3) BETWEEN 0 AND 350
and Room.Type = 6
Query optimizer could check conditions in any order so LEFT(Room.Name, 3) BETWEEN 0 AND 350
could yield conversion error.
Upvotes: 2