2010-08-19 5 views
1

trouver la valeur la plus commune sur plusieurs tables

bad_guys_1   bad_guys_2 
| id | ip  | | id | ip  | 
+----+---------+ +----+---------+ 
| 1 | 1.2.3.4 | | 1 | 1.2.3.4 | 
| 2 | 2.3.4.5 | | 2 | 4.5.6.7 | 
| 3 | 3.4.5.6 | | 3 | 1.2.3.4 | 

bad_guys_3   bad_guys_4 
| id | ip  | | id | ip  | 
+----+---------+ +----+---------+ 
| 1 | 9.8.7.6 | | 1 | 1.2.3.4 | 
| 2 | 8.7.6.5 | | 2 | 2.3.4.5 | 
| 3 | 2.3.4.5 | | 3 | 3.4.5.6 | 

Par exemple, interroger les tableaux ci-dessus devrait se traduire par quelque chose comme:

| ip  | count | 
+---------+-------+ 
| 1.2.3.4 | 4  | 
| 2.3.4.5 | 3  | 
| 3.4.5.6 | 2  | 
| 4.5.6.7 | 1  | 
| 9.8.7.6 | 1  | 
| 8.7.6.5 | 1  | 

Les vraies tables contiennent effectivement de nombreux domaines supplémentaires qui ne sont pas alignés les uns avec les autres, des tables ainsi séparées. Je ne me soucie pas vraiment de rompre les liens entre les matchs, il suffit de les énumérer par ordre décroissant en nombre. Ma base de données est PostGreSQL si l'utilisation de fonctions non standard peut aider, mais pour la portabilité, préférez utiliser sql standard si possible. Merci et laissez-moi savoir si vous avez besoin de plus de détails.

+0

Wow, c'était rapide! vous êtes géniaux les gars. Merci tout le monde. – Andy

Répondre

6

Désolé de le dire, mais les autres réponses en utilisant seulement union et non union all ont tort. Si une ligne sélectionnée apparaît dans plusieurs tables, elle ne sera comptée dans la première table que si les autres tables sont incluses via union et non pas toutes.

Pour les requêtes sélectionnant à la fois l'ID et l'adresse, la possibilité d'une ligne ayant le même ID et l'adresse dans des tables différentes existe toujours. L'utilisation de UNION ALL garantit que toutes les valeurs sont unies, qu'elles soient en double ou non, et nous voulons que les doublons puissent être comptés. Utiliser UNION ALL est souvent moins de travail pour la base de données, car il n'a pas besoin de trouver des doublons et de les supprimer.

select ip, count(*) from 
(
select ip from bad_guys_1 
union ALL 
select ip from bad_guys_2 
union ALL 
select ip from bad_guys_3 
union ALL 
select ip from bad_guys_4 
) as ranking 
group by ip 
order by count(*) DESC 
+0

oui, vous avez raison. Le faire avec juste l'union me donne un compte de 1 pour chaque résultat, mais l'union tout m'indique le nombre total de fois que chaque ip indiqué apparaît sur toutes les tables. – Andy

1

Try this ...

select ip, count(*) 
from 
(
select id, ip from bad_guys_1 
union all 
select id, ip from bad_guys_2 
union all 
select id, ip from bad_guys_3 
union all 
select id, ip from bad_guys_4 
) a 
group by ip 
order by count(*) desc 
+1

vous devez UNION ALL pas UNION, ou des valeurs répétées dans 2,3, et 4 tables ne seront pas comptées. – mdma

+0

mis à jour .. bien que la probabilité de l'ID et de la correspondance IP soit faible, vous avez raison. – Fosco

1

Andy, Vous pouvez utiliser une "union" pour créer une grande table logique (en mémoire) avec seulement les adresses IP. Ensuite, vous pouvez faire la

normale
select count(ip), ip from 
(select ip from table1 union all select ip from table2 etc) unionedTable 
group by ip 

[edited ajouter union all - merci]

+2

vous devez UNION ALL pas UNION, ou les valeurs répétées dans des tables différentes ne seront pas comptées. – mdma

+0

Fixé. Merci mdma. –

1
 select ip, count(*) from 
     (
     select id, ip from bad_guys_1 
     union all 
     select id, ip from bad_guys_2 
     union all 
     select id, ip from bad_guys_3 
     union all 
     select id, ip from bad_guys_4 
     ) as ranking 
     group by ip 

order by count(*) desc 
+1

vous devez UNION ALL pas UNION, ou des valeurs répétées dans 2,3, et 4 tables ne seront pas comptées. (En supposant qu'ils avaient aussi le même id, ce qui est possible.) – mdma

2
SELECT ip, count(*) c 
FROM 
(
    SELECT ip 
    from bad_guys_1 
    UNION ALL 
    SELECT ip 
    from bad_guys_2 
    UNION ALL 
    SELECT ip 
    from bad_guys_3 
    UNION ALL 
    SELECT ip 
    from bad_guys_4) 
group by ip 
order by 2 desc 
Questions connexes