2012-10-04 6 views
5

J'ai une table avec les noms d'utilisateur et les adresses IP.
J'ai besoin pour obtenir une liste des utilisateurs qui ont IP similaire - ignorer 3 derniers ou 2 ou 1 chiffre (s) -Sélectionnez des adresses IP similaires - ignorez les 3 derniers chiffres

Exemple:
comte 190.200.210.180 et 190.200.210.60 comme la même adresse IP.
Nombre 205.50.4.30 et 205.50.4.197 comme la même adresse IP.

Le type de champ d'adresses IP est défini comme varchar et c'est quelque chose que je ne peux pas changer pour le moment.

Actuellement, je suis en utilisant:

SELECT GROUP_CONCAT(username) names, IPs, COUNT(IPs) AS Instances 
FROM users 
GROUP BY IPs 
HAVING (COUNT(IPs) >1) 
ORDER BY `Instances ` DESC 

pour obtenir les utilisateurs avec la même adresse IP. Est-il possible avec le champ des IP étant défini comme varchar de faire une instruction select pour grouper les utilisateurs avec des ips semblables? SQL statement output

Merci d'avance pour votre aide.

Répondre

4

Essayez ceci:

SELECT 
    GROUP_CONCAT(username) AS names, 
    SUBSTRING_INDEX(IPs, '.', 3) AS IPs 
    COUNT(*) AS Instances 
FROM 
    users 
GROUP BY 
    SUBSTRING_INDEX(IPs, '.', 3) 
HAVING 
    COUNT(*) > 1 
ORDER BY 
    Instances DESC 
4

La SUBSTR_INDEX fonction permet l'analyse d'une adresse IP d'une opération facile:

SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(y.IPs,'.',1),'.',-1) a, 
     SUBSTRING_INDEX(SUBSTRING_INDEX(y.IPs,'.',2),'.',-1) b, 
     SUBSTRING_INDEX(SUBSTRING_INDEX(y.IPs,'.',3),'.',-1) c, 
     SUBSTRING_INDEX(SUBSTRING_INDEX(y.IPs,'.',4),'.',-1) d 
    FROM (SELECT ... FROM users) y 

En utilisant les octets crénelage a, b, c, d comme une base, vous devriez être en mesure d'appliquer une logique similaire à votre question et effectuer l'octet correspondant que vous désirez ...

+0

Très cool. Juste curieux, pourquoi avez-vous utilisé un sous-select dans votre clause from? – Tom

+0

L'utilisateur pourrait probablement juste grouper par a, b et c avec ce que vous avez ci-dessus. – Tom

2

Personnellement, j'irais à éliminer le dernier .nnn partie comme dans ...

SELECT 
    GROUP_CONCAT(`username` SEPARATOR ', ') AS 'names', 
    SUBSTRING(`IPs`,1,(CHAR_LENGTH(`IPs`)-CHAR_LENGTH(SUBSTRING_INDEX(`IPs`,'.',-1))-1)) AS 'roughIP', 
    COUNT(*) AS 'Instances' 
FROM `users` 
GROUP BY `roughIP` 
ORDER BY `Instances` DESC 
+1

Belle alternative. La seule chose est qu'il utilise plus de ressources, à cause de l'utilisation de SUBSTRING 2 fois et de la fonction CHAR_LENGTH également. –

+2

Vous avez raison, mais je ne suis pas sûr que chaque IP aura * n * nombre de périodes. – inhan

Questions connexes