4

IPリストをサブネット(最初の3オクテット)でグループ化してカウントする必要があります。たとえば、Ipsがある場合

123.12.12.12
123.12.12.11
123.12.11.11

私はそのような結果を得る必要があります:

123.12.12 | 2
123.12.11 | 1

私はこの例をグーグルで検索しました:

select 
substr(ip,1,locate('.',ip,locate('.',ip)+1)-1) 
as ip, count(ip) as count
from ip_list
group by ip ORDER BY count  DESC

ただし、リストは最初の2オクテットでのみグループ化されます。私はこれらすべてで迷子になりましたlocate(locate(locate(...)))。誰かがこれを修正して適切な結果を得るのを手伝ってもらえますか?

4

4 に答える 4

8

group by 式名を使用する必要があります。

select 
--   locate( '.', ip, locate( '.', ip, locate( '.', ip ) + 1 ) + 1 ) as l,
   substr( ip, 1, locate( '.', ip
                          , locate( '.', ip
                                    , locate( '.', ip ) + 1 ) + 1 ) - 1 ) as subip,
   count(ip) as count
from ip_list
group by ( subip )
order by count desc
;

編集1
の使用locateは必要ありません。SUBSTR_INDEXIPのサブセットをフィルタリングするために使用できます。

select
       substring_index( ip, '.', 3 ) as subip
     , count(ip) as count
  from ip_list
 group by ( subip )
 order by count desc

ドキュメントを参照してください

于 2012-06-03T11:45:53.697 に答える
1

このロジックを使用すると、別のレイヤーが必要になると思いますlocate

substr(ip, 1, locate('.', ip, locate('.', ip, locate('.', ip)+1) +1) - 1)
于 2012-06-03T11:42:05.173 に答える
1

あなたが使うことができます

GROUP BY INET_ATON(ip)/256
于 2012-06-03T11:49:39.057 に答える
0

IPバイナリを作成する場合は、IPアドレスの最初の3つの部分のみを保持するマスクをその上に適用できます。マスクは次のようになります。

11111111111111111111111100000000

したがって、数字としては、次のようになります。

SELECT CONV('11111111111111111111111100000000' ,2,10) as mask;
-- Result: 4294967040

このマスクを使用してIPアドレスをビット単位でANDすると、次のような結果が得られます。

SELECT
'1.0.207.199',                
INET_NTOA( INET_ATON( '1.0.207.199') & 4294967040 ) ;
-- Result:
-- 1.0.207.199
-- 1.0.207.0

INET_ATONはip(A)ddress(TO)a(N)umberを変換し、INET_NTOAはその逆に変換します(実際の意味はASCII TO Networkを表しますが、私はこのshofthandの方が好きです;-)。

したがって、次のようにIPアドレスでグループ化できます。

SELECT
    INET_NTOA( INET_ATON( ip ) & 4294967040 ) AS ipgroup, 
    COUNT(ip) AS count
FROM ip_list
GROUP BY ipgroup 
ORDER BY count DESC;

お役に立てば幸いです。

于 2017-05-26T14:37:36.343 に答える