如何在事先不知道数量的情况下制作多个 BETWEEN 语句? (通过IP范围检测国家)

Posted

技术标签:

【中文标题】如何在事先不知道数量的情况下制作多个 BETWEEN 语句? (通过IP范围检测国家)【英文标题】:How to make multiple BETWEEN statements not knowing the quantity of them beforehand? (detecting country by IP range) 【发布时间】:2016-03-02 09:47:52 【问题描述】:

我有带有 ip_from、ip_to、country_code 列的 Ip2LocationLite 数据库。

所有 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 期望一个音调而不是 3 千个音调。

如何对其进行编程以使其在 BETWEEN 之间产生 3000 个? (根据要检查的音调数量)

【问题讨论】:

你能从这些表中显示几行吗? 【参考方案1】:

如果没有一些示例记录和预期的输出,回答这些问题可能会有些棘手。但是,如果我正确理解了您的架构,您可以使用联接而不是子查询。

示例

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'
;

【讨论】:

你理解一切正确,拯救了我的一天。非常感谢你!我觉得现在使用 ip2location 数据库很初级。 优秀。很高兴我能帮上忙。有关 JOINS 的更多信息,请参阅article, from Microsoft。【参考方案2】:

你能试试这个吗..

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'
    )

【讨论】:

【参考方案3】:

从您的第一个子查询中获取 min/lowest 值和从您的第二个子查询中获取 max/highest 值以避免错误,如果您想将它们用作 BETWEEN 子句的参数。

如果您的 IP 地址是规范的或可以按数字排序,您可以通过按 ASC 顺序对它们进行排序并选择第一行(即SELECT TOP 1)来获得最低 IP 值,然后通过将它们排序来获得最高 IP 值DESC 顺序并选择第一行。

【讨论】:

以上是关于如何在事先不知道数量的情况下制作多个 BETWEEN 语句? (通过IP范围检测国家)的主要内容,如果未能解决你的问题,请参考以下文章

Ada - (Streams) 如何在事先不知道字符串长度的情况下正确调用 String'Read()

如何在不停止递归的情况下返回递归函数中的值?

在不知道学生人数和每个学生课程数量的情况下对学生的平均成绩排序

在不知道 SQL 中的列的情况下创建表

从多个numpy数组中制作一个巨大的dict

如何在不重新加载页面的情况下制作多个帖子(html,mysql)