如何在事先不知道数量的情况下制作多个 BETWEEN 语句? (通过 IP 范围检测国家)
How to make multiple BETWEEN statements not knowing the quantity of them beforehand? (detecting country by IP range)
我的 Ip2LocationLite 数据库有 ip_from、ip_to、country_code 列。
所有 IP 均为十进制格式(使用函数转换)。
所以我必须检测那些具有来自特定国家/地区的 IP 地址的用户。
例如,俄罗斯有超过 3000 个 IP 范围,我想搜索所有这些范围。
脚本如下所示:
SELECT * FROM [dbo].[USERINFO] as UserInfo
WHERE (SELECT gaminator.dbo.IPAddressToInteger (UserInfo.LastIp)) BETWEEN
(
SELECT [ip2location].[dbo].[ip2location_db1].ip_from FROM [ip2location].[dbo].[ip2location_db1]
WHERE [ip2location].[dbo].[ip2location_db1].country_code = 'RU'
)
AND
(
SELECT [ip2location].[dbo].[ip2location_db1].ip_to FROM [ip2location].[dbo].[ip2location_db1]
WHERE [ip2location].[dbo].[ip2location_db1].country_code = 'RU'
)
最后一件事报错:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
这是因为 BETWEEN 需要一个音阶而不是 3000 个音阶。
如何对此进行编程,使其变成 3000 个 BETWEEN? (根据要检查的音符数量)
从第一个子查询中获取 min/lowest
值,从第二个子查询中获取 max/highest
值以避免错误,如果您想将它们用作 [=] 的参数12=] 子句。
如果您的 IP 地址是规范的或可以按数字排序,您可以通过按 ASC 顺序和 select 第一行(即 SELECT TOP 1
)对它们进行排序来获得最低的 IP 值并获得通过按 DESC 顺序对它们进行排序来获得最高 IP 值,并且 select 第一行也是如此。
你能试试这个吗..
sELECT * FROM [dbo].[USERINFO] as UserInfo
WHERE (SELECT gaminator.dbo.IPAddressToInteger (UserInfo.LastIp)) BETWEEN
(
SELECT min([ip2location].[dbo].[ip2location_db1].ip_from )FROM [ip2location].[dbo].[ip2location_db1]
WHERE [ip2location].[dbo].[ip2location_db1].country_code = 'RU'
)
AND
(
SELECT max([ip2location].[dbo].[ip2location_db1].ip_to) FROM [ip2location].[dbo].[ip2location_db1]
WHERE [ip2location].[dbo].[ip2location_db1].country_code = 'RU'
)
如果没有一些样本记录和预期的输出,回答这些问题可能有点棘手。但是,如果我正确理解了您的模式,您可以使用连接而不是子查询。
例子
SELECT
*
FROM
[dbo].[USERINFO] as UserInfo
INNER JOIN [ip2location].[dbo].[ip2location_db1] AS ipRange ON UserInfo.LastIp BETWEEN ipRange.ip_to AND ipRange.ip_from
WHERE
ipRange.country_code = 'RU'
;
我的 Ip2LocationLite 数据库有 ip_from、ip_to、country_code 列。
所有 IP 均为十进制格式(使用函数转换)。
所以我必须检测那些具有来自特定国家/地区的 IP 地址的用户。 例如,俄罗斯有超过 3000 个 IP 范围,我想搜索所有这些范围。
脚本如下所示:
SELECT * FROM [dbo].[USERINFO] as UserInfo
WHERE (SELECT gaminator.dbo.IPAddressToInteger (UserInfo.LastIp)) BETWEEN
(
SELECT [ip2location].[dbo].[ip2location_db1].ip_from FROM [ip2location].[dbo].[ip2location_db1]
WHERE [ip2location].[dbo].[ip2location_db1].country_code = 'RU'
)
AND
(
SELECT [ip2location].[dbo].[ip2location_db1].ip_to FROM [ip2location].[dbo].[ip2location_db1]
WHERE [ip2location].[dbo].[ip2location_db1].country_code = 'RU'
)
最后一件事报错:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
这是因为 BETWEEN 需要一个音阶而不是 3000 个音阶。
如何对此进行编程,使其变成 3000 个 BETWEEN? (根据要检查的音符数量)
从第一个子查询中获取 min/lowest
值,从第二个子查询中获取 max/highest
值以避免错误,如果您想将它们用作 [=] 的参数12=] 子句。
如果您的 IP 地址是规范的或可以按数字排序,您可以通过按 ASC 顺序和 select 第一行(即 SELECT TOP 1
)对它们进行排序来获得最低的 IP 值并获得通过按 DESC 顺序对它们进行排序来获得最高 IP 值,并且 select 第一行也是如此。
你能试试这个吗..
sELECT * FROM [dbo].[USERINFO] as UserInfo
WHERE (SELECT gaminator.dbo.IPAddressToInteger (UserInfo.LastIp)) BETWEEN
(
SELECT min([ip2location].[dbo].[ip2location_db1].ip_from )FROM [ip2location].[dbo].[ip2location_db1]
WHERE [ip2location].[dbo].[ip2location_db1].country_code = 'RU'
)
AND
(
SELECT max([ip2location].[dbo].[ip2location_db1].ip_to) FROM [ip2location].[dbo].[ip2location_db1]
WHERE [ip2location].[dbo].[ip2location_db1].country_code = 'RU'
)
如果没有一些样本记录和预期的输出,回答这些问题可能有点棘手。但是,如果我正确理解了您的模式,您可以使用连接而不是子查询。
例子
SELECT
*
FROM
[dbo].[USERINFO] as UserInfo
INNER JOIN [ip2location].[dbo].[ip2location_db1] AS ipRange ON UserInfo.LastIp BETWEEN ipRange.ip_to AND ipRange.ip_from
WHERE
ipRange.country_code = 'RU'
;