Php 在SQL中按IP地址排序的最佳方法

Php 在SQL中按IP地址排序的最佳方法,php,sql,sqlite,spiceworks,Php,Sql,Sqlite,Spiceworks,我使用SQLITE3 PDO通过PHP连接到我的SpiceWorks数据库。我试图按IP地址顺序显示设备列表。以下是我当前的查询: SELECT name, ip_address FROM `devices` ORDER BY ip_address 问题是,它会像这样组织它们: SELECT IP FROM iplist ORDER BY CAST(substr(trim(IP),1,instr(trim(IP),'.')-1) AS INTEGER), CAST(substr(

我使用SQLITE3 PDO通过PHP连接到我的SpiceWorks数据库。我试图按IP地址顺序显示设备列表。以下是我当前的查询:

SELECT name, ip_address FROM `devices` ORDER BY ip_address
问题是,它会像这样组织它们:

SELECT IP FROM iplist ORDER BY

CAST(substr(trim(IP),1,instr(trim(IP),'.')-1) AS INTEGER),  

   CAST(substr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)) ,1, instr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)),'.')-1) AS INTEGER), 

        CAST(substr(substr(trim(IP),length(substr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)) ,1, instr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)),'.')))+length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)) ,1, instr(substr(trim(IP),length(substr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)) ,1, instr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)),'.')))+length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)),'.')-1) AS INTEGER), 

        CAST(substr(trim(IP),length(substr(substr(trim(IP),length(substr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)) ,1, instr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)),'.')))+length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)) ,1, instr(substr(trim(IP),length(substr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)) ,1, instr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)),'.')))+length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)),'.')))+ length(substr(trim(IP),1,instr(trim(IP),'.')))+length(substr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)) ,1, instr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)),'.')))+1,length(trim(IP))) AS INTEGER)

有什么简单的方法可以解决这个问题吗


我不可能编辑数据库,因为它会关闭。我需要一种在SQL中实现这一点的方法。

您将字段作为VARCHAR或其他字符字段,因此它是按第一个数字对它们进行排序。您需要将类型强制转换为order by语句中的数字

像这样:

SELECT name, ip_address
FROM devices
ORDER BY

CAST(PARSENAME([ip_address], 4) AS INT),
CAST(PARSENAME([ip_address], 3) AS INT),
CAST(PARSENAME([ip_address], 2) AS INT),
CAST(PARSENAME([ip_address], 1) AS INT)
只是不确定这是否适用于SQLlite

ORDER BY
CAST(substr(ip_address,1,instr(ip_address,'.')) AS NUMERIC),
CAST(substr(ip_address,instr(ip_address,'.'), instr(substr(ip_address,instr(ip_address,'.')))) AS NUMERIC),

这样的办法应该行得通。不过会很糟糕的。(这个应该按前两个八位字节排序…

我实现了如下:

SELECT IP FROM iplist ORDER BY

CAST(substr(trim(IP),1,instr(trim(IP),'.')-1) AS INTEGER),  

   CAST(substr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)) ,1, instr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)),'.')-1) AS INTEGER), 

        CAST(substr(substr(trim(IP),length(substr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)) ,1, instr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)),'.')))+length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)) ,1, instr(substr(trim(IP),length(substr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)) ,1, instr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)),'.')))+length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)),'.')-1) AS INTEGER), 

        CAST(substr(trim(IP),length(substr(substr(trim(IP),length(substr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)) ,1, instr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)),'.')))+length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)) ,1, instr(substr(trim(IP),length(substr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)) ,1, instr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)),'.')))+length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)),'.')))+ length(substr(trim(IP),1,instr(trim(IP),'.')))+length(substr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)) ,1, instr(substr(trim(IP),length(substr(trim(IP),1,instr(trim(IP),'.')))+1,length(IP)),'.')))+1,length(trim(IP))) AS INTEGER)

你试过INET_ATON函数吗?这可能是一个迟来的答案,但可能会帮助其他人

SELECT name, ip_address
FROM devices
ORDER BY
INET_ATON(ip_address)

因为我只关心最后一个八位组,所以我能够使用非常简单的

SELECT name, ip_address FROM `devices`
ORDER BY CAST(substr(ip_address, 10) AS NUMERIC) DESC;

我的ip在最后一个八位字节之前有9个字符

,这取决于您存储ip地址的方式。它是一个字符串列吗?如果是这样,那就是你的问题。是的。SpiceWorks将其存储在varchar字段中。我没有办法改变这一点,因为SpiceWorks也使用数据库。你必须根据需要将其分为由每个点和顺序分隔的子字符串。Mysql有子字符串索引,我不熟悉sqlite。我不确定sqlite,但在Mysql中,你可以
按INET\u ATON(ip\u地址)排序
。。。不知道sqlite是否有类似的函数inet\u ATON不是有效的sqlite函数。没有这样的函数:PARSENAME。。。PARSENAME不是有效的SQLITE函数。我发现:基本上,按字符串从第一个字母到第一个点排序,然后从第一个点到第一个点后的下一个点排序……这仍然不起作用,它仍然会在
20
之前排序
113
。您需要将每个子字符串转换为一个数字以进行排序。^Fixed。增加了演员阵容——注意,我目前无法测试这一点;这里面可能会有一些不错的东西。大家看下面我的答案。它会起作用的。百分之百正确。在我的项目中,它已经实现了。
INET\u ATON
是一个MySQL函数。问题是关于SQLITE的。