检查数字是否在字符串范围内
Check whether a number is in a string range
我有一个table
ID
Count
Range
1
33
1-100
2
120
101-200
3
155
201-300
Range
是一个字符串,只能有值1-100
、101-200
、201-300
。我需要编写一个查询来检查计数和范围是否合适,因此应该弹出 155。
我的想法是:
select *
from Tabe
where Count between (select value from string_split(Range, '-'))
但这不起作用。有人可以帮我吗?
我马上建议您更改 table 结构,为每个范围的下限和上限设置单独的列:
| ID | Count | lower_range | upper_range |
| 1 | 33 | 1 | 100 |
| 2 | 120 | 101 | 200 |
| 3 | 155 | 201 | 300 |
有了这个改进的设计,你只需要一个简单的查询:
SELECT *
FROM yourTable
WHERE Count BETWEEN lower_range AND upper_range;
这种方法的优点是上面的查询是完全可搜索的(即可以使用索引,应该定义一个 suitable )。它还避免了您必须做一些 SQL 奥林匹克运动会来隔离每个 hypenated 范围字符串的下部和上部组件。由于您的目的是将这些数字用作 数字 ,只需改用上述设计即可。
编辑:
如果您真的坚持这种设计,可以使用以下查询:
SELECT *
FROM yourTable
WHERE
Count BETWEEN CAST(SUBSTRING([Range], 1, CHARINDEX('-', [Range]) - 1) AS int) AND
CAST(SUBSTRING([Range], CHARINDEX('-', [Range]) + 1, LEN([Range])) AS int);
如果可能,您可以更改 table 的结构,例如添加两列
最小范围:整数
最大范围:整数
SELECT *
FROM TableName
WHERE Count BETWEEN MinRange AND MaxRange
不需要解析 Range
因为它只能有三个特定值之一:
-- Sample data (assuming that Count is not a string).
declare @Tabe as Table ( Id Int, [Count] Int, [Range] VarChar(10) );
insert into @Tabe ( Id, [Count], [Range] ) values
( 1, 33, '1-100' ), ( 2, 120, '101-200' ), ( 3, 155, '201-300' );
select * from @Tabe;
-- Using case expressions.
select *
from @Tabe
where [Count] between
case Range
when '1-100' then 1
when '101-200' then 101
when '201-300' then 201 end
and
case Range
when '1-100' then 100
when '101-200' then 200
when '201-300' then 300 end;
-- Using an on-the-fly lookup table.
select T.*
from @Tabe as T inner join
( values ( '1-100', 1, 100 ), ( '101-200', 101, 200 ), ( '201-300', 201, 300 ) )
as Ranges( [Range], Low, High ) on T.[Range] = Ranges.[Range]
where T.[Count] between Ranges.Low and Ranges.High;
当 Range
具有意外值时,任何一种方法都会失败。
我有一个table
ID |
Count |
Range |
---|---|---|
1 | 33 | 1-100 |
2 | 120 | 101-200 |
3 | 155 | 201-300 |
Range
是一个字符串,只能有值1-100
、101-200
、201-300
。我需要编写一个查询来检查计数和范围是否合适,因此应该弹出 155。
我的想法是:
select *
from Tabe
where Count between (select value from string_split(Range, '-'))
但这不起作用。有人可以帮我吗?
我马上建议您更改 table 结构,为每个范围的下限和上限设置单独的列:
| ID | Count | lower_range | upper_range |
| 1 | 33 | 1 | 100 |
| 2 | 120 | 101 | 200 |
| 3 | 155 | 201 | 300 |
有了这个改进的设计,你只需要一个简单的查询:
SELECT *
FROM yourTable
WHERE Count BETWEEN lower_range AND upper_range;
这种方法的优点是上面的查询是完全可搜索的(即可以使用索引,应该定义一个 suitable )。它还避免了您必须做一些 SQL 奥林匹克运动会来隔离每个 hypenated 范围字符串的下部和上部组件。由于您的目的是将这些数字用作 数字 ,只需改用上述设计即可。
编辑:
如果您真的坚持这种设计,可以使用以下查询:
SELECT *
FROM yourTable
WHERE
Count BETWEEN CAST(SUBSTRING([Range], 1, CHARINDEX('-', [Range]) - 1) AS int) AND
CAST(SUBSTRING([Range], CHARINDEX('-', [Range]) + 1, LEN([Range])) AS int);
如果可能,您可以更改 table 的结构,例如添加两列 最小范围:整数 最大范围:整数
SELECT *
FROM TableName
WHERE Count BETWEEN MinRange AND MaxRange
不需要解析 Range
因为它只能有三个特定值之一:
-- Sample data (assuming that Count is not a string).
declare @Tabe as Table ( Id Int, [Count] Int, [Range] VarChar(10) );
insert into @Tabe ( Id, [Count], [Range] ) values
( 1, 33, '1-100' ), ( 2, 120, '101-200' ), ( 3, 155, '201-300' );
select * from @Tabe;
-- Using case expressions.
select *
from @Tabe
where [Count] between
case Range
when '1-100' then 1
when '101-200' then 101
when '201-300' then 201 end
and
case Range
when '1-100' then 100
when '101-200' then 200
when '201-300' then 300 end;
-- Using an on-the-fly lookup table.
select T.*
from @Tabe as T inner join
( values ( '1-100', 1, 100 ), ( '101-200', 101, 200 ), ( '201-300', 201, 300 ) )
as Ranges( [Range], Low, High ) on T.[Range] = Ranges.[Range]
where T.[Count] between Ranges.Low and Ranges.High;
当 Range
具有意外值时,任何一种方法都会失败。