1

次の単純な 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   172.16.b
2013-06-19      12455   172.16.a
2013-06-19      5205    172.16.c

つまり、指示に従って、IP を日付順に並べ替え、次にカウント順に並べ替えます。

今、結果を次のようにしたいと思います。

  • 最初に TODAY カウントが最も高い IP を表示し、
  • 次に、過去数日間のその IP のカウントを表示します (cnt とは無関係)。
  • 次に、TODAY で 2 番目に高いカウントを持つ IP を表示します。
  • そのIPの履歴、
  • など。

望ましい結果の例:

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

これはまだ完全ではありません。下のブロックが一番上にあるはずです。

4

3 に答える 3

1

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、2 つの現在のカウントが同じ場合に対処します。

他のデータベースではnow()、sysdate()`、CURRENT_TIMESTAMP、またはそのようなものや現在の日付を使用する場合があります。

于 2013-06-21T15:32:23.353 に答える
0

以下はうまくいくようです。ありがとう。

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
  • str_to_date が使用されるのは、形式が最初は実際の日付型ではないためです
  • いくつかの WHERE 条件があります。それらが内部クエリと外部クエリに存在することに注意する必要があります。
  • latest_count は昨日のものであるため、subdate が使用されます (ただし、これは詳細です。今日でも機能します)。

最終的に、次のような素晴らしい結果が得られます。

'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'
....

機能するものに最も近いため、Mark Ba​​nnister の回答を受け入れています。

于 2013-06-21T17:31:22.550 に答える