我有一个名为的表iphdr
,它有两个字段ip_src
,并ip_dst
以数字(inet_aton)形式存储 IP。我需要为我的 webapp 获取最常出现的源、目标和(源+目标)IP。我正在使用带有金字塔的 SQLalchemy。
频繁出现的源/目的IP
这是简单的部分。我只是按组计数并得到结果
mysql> select inet_ntoa(ip_dst) as ip,count(*) as count1 from iphdr group by ip;
+--------------+--------+
| ip | count1 |
+--------------+--------+
| 192.168.1.22 | 13 |
| 192.168.2.8 | 1 |
| 31.1.1.22 | 1 |
| 31.21.18.100 | 905 |
| 31.21.18.221 | 4 |
+--------------+--------+
5 rows in set (0.00 sec)
SQLAlchemy 中对应的语句是
>>>top_srcs = session.query(func.inet_ntoa(IpHdr.ip_dst).label('ip'),func.count('*').label('ip_count')).group_by('ip').order_by(desc('ip_count'))
>>>print top_srcs.all()
[('31.21.18.100', 905L), ('192.168.1.22', 13L), ('31.21.18.221', 4L), ('192.168.2.8', 1L), ('31.1.1.22', 1L)]
频繁出现的Src+Dest按count排序
在 MySQL 中,我可以通过使用 union all 来组合各个 src/dest 查询轻松地做到这一点
mysql> select
m.ip,sum(m.count1) as c
from
(
select
inet_ntoa(ip_dst) as ip,count(*) as count1
from iphdr group by ip
union all
select
inet_ntoa(ip_src) as ip,count(*) as count1
from iphdr group by ip
)
as m group by m.ip order by c desc;
+---------------+------+
| ip | c |
+---------------+------+
| 31.21.18.100 | 924 |
| 192.168.2.10 | 186 |
| 31.21.18.101 | 171 |
| 192.168.2.9 | 165 |
| 192.168.2.8 | 96 |
| 192.168.2.4 | 84 |
| 192.168.2.5 | 78 |
| 192.168.2.6 | 38 |
| 192.168.1.22 | 31 |
| 31.1.1.9 | 25 |
| 31.11.100.101 | 17 |
| 192.168.2.7 | 17 |
| 31.21.18.221 | 6 |
| 192.168.33.10 | 6 |
| 31.1.1.22 | 4 |
+---------------+------+
15 rows in set (0.01 sec)
但是在 SQLALchemy 中,尝试以相同的方式组合这两个语句会给我带来各种错误
top_srcs = session.query(func.inet_ntoa(IpHdr.ip_src).label('ip'),func.count('*').label('ip_count')).group_by('ip').order_by(desc('ip_count'))
top_dsts = session.query(func.inet_ntoa(IpHdr.ip_dst).label('ip'),func.count('*').label('ip_count')).group_by('ip').order_by(desc('ip_count'))
mod_top_srcs = top_srcs.subquery().select()
mod_top_dsts = top_dsts.subquery().select()
x = union_all(mod_top_srcs,mod_top_dsts).select()
top_total = session.query(x).group_by('ip').order_by(desc('total'))
OperationalError: (OperationalError) (1248, 'Every derived table must have its own alias
我查看了此线程,但该解决方案对我不起作用
编辑
我用别名鬼混(因为那是最初的错误)并设法编写了以下语句
>>>ts = top_srcs.subquery().select()
>>>td = top_dsts.subquery().select()
>>>session.query('ip','ip_count').select_from(union_all(ts,td).alias('mno').select().alias('abc')).all()
[('192.168.2.10', 186L), ('31.21.18.101', 171L), ('192.168.2.9', 165L), ('192.168.2.8', 95L), ('192.168.2.4', 84L), ('192.168.2.5', 78L), ('192.168.2.6', 38L), ('31.1.1.9', 25L), ('31.21.18.100', 19L), ('192.168.1.22', 18L), ('31.11.100.101', 17L), ('192.168.2.7', 17L), ('192.168.33.10', 6L), ('31.1.1.22', 3L), ('31.21.18.221', 2L), ('31.21.18.100', 905L), ('192.168.1.22', 13L), ('31.21.18.221', 4L), ('192.168.2.8', 1L), ('31.1.1.22', 1L)]
但试图得到总和打破了它
>>> session.query('ip',sum('ip_count')).select_from(union_all(ts,td).alias('mno').select().alias('abc')).group_by('abc.ip').all()
[('192.168.1.22', 0.0), ('192.168.2.10', 0.0), ('192.168.2.4', 0.0), ('192.168.2.5', 0.0), ('192.168.2.6', 0.0), ('192.168.2.7', 0.0), ('192.168.2.8', 0.0), ('192.168.2.9', 0.0), ('192.168.33.10', 0.0), ('31.1.1.22', 0.0), ('31.1.1.9', 0.0), ('31.11.100.101', 0.0), ('31.21.18.100', 0.0), ('31.21.18.101', 0.0), ('31.21.18.221', 0.0)]
我认为我需要在查询部分中添加其他内容才能使其正常工作
任何帮助表示赞赏