2010-11-20 81 views
0

我有一个访问表(visit_table),结构:MySQL - 如何GROUP BY另一个查询的结果?

  • ID
  • IP_地址
  • 时间戳

和表(country_table)与IP国名范围

  • ID
  • begin_IP(启动IP范围)
  • 起点ip-终点(IP范围的端部)
  • begin_num(begin_IP的数值相当于,即INET_ATON(begin_IP))
  • END_NUM
  • COUNTRY_CODE的(例如美国)
  • COUNTRY_NAME
    (基于http://www.maxmind.com/app/csv

我使用MySQL 5.0.67,并想编写一个查询返回按国家访问的次数,这样的东西沿着线:

SELECT country.table.country_name, 
     count(distinct visit_table.IP_address) 
    FROM country_table, visit_table 
    WHERE country_name = (SELECT country_name 
          FROM country_table 
          WHERE INET_ATON(visits.IP_address) >= begin_num 
          AND INET_ATON(visits.IP_Address) <= end_num 
          LIMIT 0,1) 
GROUP BY country_table.country_name 

我很确定我做错了什么,但不知道如何解决 - 某种JOIN或做某事与SELECT或GROUP BY语句?任何指针欢迎!

+0

我想你可以通过子句中使用子查询的形式编写组中的select语句。这适用于Oracle,也许它也适用于MySQL。有人能证实这一点吗? – Falcon 2010-11-21 10:47:00

回答

1

是的,你想加入:

SELECT country_table.country_name, count(distinct visit_table.IP_address) 
FROM country_table 
RIGHT JOIN visit_table ON visit_table.id=country_table.id  
GROUP BY country_table.country_name 
3

用途:

SELECT c.country_name, 
     COUNT(DISTINCT v.IP_address) 
    FROM COUNTRY_TABLE c 
    JOIN VISIT_TABLE v ON v.country_name = c.country_name 
    WHERE INET_ATON(v.IP_Address) BETWEEN begin_num AND end_num 
GROUP BY c.country_name 

如果有该IP范围内没有一个国家,你不会得到任何东西。但是如果范围内有多个国家返回,则需要更新查询以处理该查询。

如果你想有一个国家,可能没有捕捉到它的IP地址,使用:

SELECT c.country_name, 
      COUNT(DISTINCT v.IP_address) 
    FROM COUNTRY_TABLE c 
LEFT JOIN VISIT_TABLE v ON v.country_name = c.country_name 
    WHERE INET_ATON(v.IP_Address) BETWEEN begin_num AND end_num 
GROUP BY c.country_name 
+0

c.country_code会更快吗? – Pentium10 2010-11-20 22:04:15

+0

@ Pentium10:按照使用较少字节存储该值的数据类型进行分组或JOIN应该表现更好。可能会考虑索引,但会对INSERT/UPDATE/DELETE查询产生负面影响... – 2010-11-20 22:05:40