Mysql SQL按条件计数排序,显示历史记录
考虑以下简单的MySQL查询:Mysql SQL按条件计数排序,显示历史记录,mysql,sql,Mysql,Sql,考虑以下简单的MySQL查询: SELECT date, count(*) cnt, ip FROM fwlog GROUP BY ip, date HAVING cnt>100 ORDER BY date DESC, cnt DESC 它给我的感觉是: date cnt src 2013-06-20 14441 172.16.a 2013-06-20 8887 172.16.b .... 2013-06-19 14606 17
SELECT date, count(*) cnt, ip
FROM fwlog
GROUP BY ip, date
HAVING cnt>100
ORDER BY date DESC, cnt DESC
它给我的感觉是:
date cnt src
2013-06-20 14441 172.16.a
2013-06-20 8887 172.16.b
....
2013-06-19 14606 172.16.b
2013-06-19 12455 172.16.a
2013-06-19 5205 172.16.c
也就是说,它按日期对IP进行排序,然后按照指示按计数进行排序
现在我希望结果是:
- 首先显示今天计数最高的IP
- 然后显示最近几天该IP的计数(独立于cnt)
- 然后显示今天第二个最高计数的IP
- 那么这个IP的历史,
- 等等,pp
date cnt src
2013-06-20 14441 172.16.a
2013-06-19 12455 172.16.a
2013-06-18 .... 172.16.a
2013-06-17 .... 172.16.a
....
2013-06-20 8887 172.16.b
2013-06-19 14606 172.16.b
2013-06-18 .... 172.16.b
2013-06-17 .... 172.16.b
...
2013-06-20 .... 172.16.c
2013-06-19 .... 172.16.c
2013-06-18 .... 172.16.c
2013-06-17 .... 172.16.c
...
...
甚至可以使用普通SQL来实现这一点吗
再见
马尔基
==========================================
@戈登·林诺夫:
SELECT
datex,
cnt,
ip
FROM
fwlog
WHERE
...
GROUP BY ip , datex
ORDER BY SUM(case
when datex = DATE(NOW()) then 1
else 0
end) DESC , src, date DESC, cnt DESC
2013-06-20 47 10.11.y
2013-06-19 47 10.11.y
2013-06-18 45 10.11.y
2013-06-17 42 10.11.y
2013-06-16 14 10.11.y
....
2013-06-20 592 172.16.a
2013-06-19 910 172.16.a
2013-06-18 594 172.16.a
2013-06-17 586 172.16.a
2013-06-20 299 172.16.b
这还不完全正确,下面的块应该在顶部。您需要在
order by
子句中添加当前日期的计数。获取当前日期因数据库而异。以下是SQL Server的版本:
SELECT date, count(*) cnt, ip
FROM fwlog
GROUP BY ip, date
HAVING cnt > 100
ORDER BY SUM(case when date = cast(GETDATE() as date) then 1 else 0 end) desc,
ip,
date DESC, cnt DESC
ip
上的排序处理两个具有相同当前计数的情况
其他数据库可能使用now()
、sysdate()`、CURRENT_TIMESTAMP或类似的东西或当前日期。尝试:
SELECT a.`date`, count(*) cnt, a.ip
FROM fwlog a
JOIN (SELECT ip, count(*) today_count
FROM fwlog
where `date` = date(now())
group by ip) t
ON a.ip = t.ip and t.today_count > 100
GROUP BY a.ip, a.date
ORDER BY t.today_count DESC, a.ip, a.`date` DESC
下面的方法似乎有效。谢谢
SELECT
str_to_date(a.date, _utf8'%e%b%Y') datex,
count(*) cnt,
a.src
FROM
fwlog a
JOIN
(SELECT
src, count(*) latest_count
FROM
fwlog
WHERE
str_to_date(fwlog.date, '%e%b%Y') = subdate(current_date, 1)
AND ((fwlog.action <> 'accept')
AND (fwlog.message_info <> 'Implied rule')
AND (fwlog.proto NOT IN ('icmp' , 'igmp')))
GROUP BY src) b ON a.src = b.src AND b.latest_count > 10
WHERE
((a.action <> 'accept')
AND (a.message_info <> 'Implied rule')
AND (a.proto NOT IN ('icmp' , 'igmp')))
GROUP BY a.src , datex
ORDER BY b.latest_count DESC , a.src , datex DESC
我接受马克·班尼斯特的答案,因为它最接近实际情况。您使用的是哪种RDBMS?“显示过去几天该IP的计数”-多少天?数据库中只有那么多天的历史记录。无论有多少个,它们都会显示出来。我相信你在内部声明中忘记了GROUP BY,但是对于其余部分,你的想法是有效的,正如你在下面看到的。
'2013-06-20', '14441', '172.16.a'
'2013-06-19', '14606', '172.16.a'
'2013-06-18', '14338', '172.16.a'
'2013-06-17', '7665', '172.16.a'
'2013-06-20', '8887', '172.16.b'
'2013-06-19', '12455', '172.16.b'
'2013-06-18', '10040', '172.16.b'
'2013-06-20', '5744', '172.16.c'
....