gpt4 book ai didi

mysql - 按 MySQL 中的前 N ​​个分组

转载 作者:行者123 更新时间:2023-11-29 05:46:23 25 4
gpt4 key购买 nike

在 stackoverflow 上有很多 SQL Top N 问题,但我似乎找不到与我所遇到的情况相匹配的问题。我想在前 n 个查询中执行一些分组。我的数据看起来像这样(显然带有假值)。

MY_DATE    IP_ADDRESS
1/1/09 999.999.999.999
1/1/09 999.999.999.999
1/1/09 999.999.999.998
... a lot more rows

该表的日期范围涵盖几个月,每个月有数千行。我想做的是让一个查询告诉我每个月最频繁出现的 10 个 IP 地址。我可以使用以下方法在一个月内执行此操作:

SELECT DATE_FORMAT(MY_DATE, '%b-%y') AS "MONTH", IP_ADDRESS, COUNT(*) AS HITS
FROM MY_DATA
WHERE DATE_FORMAT(MY_DATE, '%b-%y') = 'JAN-09'
GROUP BY DATE_FORMAT(MY_DATE, '%b-%y'), IP_ADDRESS
ORDER BY HITS DESC
LIMIT 10

但我真正想要的是能够看到数据集中每个月的前 n 个。这基本上禁止我使用我指定的 where 子句。当然,当我这样做时,所有月份我都会得到 10 分。我正在寻找的结果应该是这样的:

MONTH    IP_ADDRESS        COUNT(*)
JAN-09 999.999.999.999 200
JAN-09 999.999.999.998 150
... ( 8 more rows of January )
FEB-09 999.999.999.999 320
FEB-09 999.999.999.998 234
... ( 8 more rows of February)
MAR-09 999.999.999.999 440
... ETC.

这可以在 MySQL 中完成吗?看来我遇到的障碍是 MySQL 不允许在 UNION 中包含的查询语句中使用 ORDER BY。感谢您的帮助!

最佳答案

我刚刚尝试了一个与 given 非常相似的查询由@Charles Bretana 提供,它确实有效。我使用 VIEW 来帮助澄清事情。

CREATE TABLE my_data (
my_date DATE,
ip_address CHAR(15)
);

插入一组日期/IP 地址对(未显示)...

为每个月和 IP 地址的所有计数创建一个 View :

CREATE VIEW my_data_per_month as
SELECT EXTRACT(YEAR_MONTH FROM my_date) AS month,
ip_address, COUNT(*) AS hits
FROM my_data
GROUP BY month, ip_address;

SELECT * FROM my_data_per_month
ORDER BY month ASC, hits DESC;

+--------+-----------------+------+
| month | ip_address | hits |
+--------+-----------------+------+
| 200901 | 999.999.999.999 | 8 |
| 200901 | 999.999.999.998 | 6 |
| 200901 | 999.999.999.997 | 5 |
| 200901 | 999.999.999.996 | 4 |
| 200901 | 999.999.999.995 | 3 |
| 200901 | 999.999.999.994 | 2 |
| 200902 | 999.999.999.998 | 8 |
| 200902 | 999.999.999.997 | 6 |
| 200902 | 999.999.999.996 | 5 |
| 200902 | 999.999.999.995 | 4 |
| 200902 | 999.999.999.994 | 3 |
| 200902 | 999.999.999.993 | 2 |
| 200903 | 999.999.999.997 | 8 |
| 200903 | 999.999.999.996 | 6 |
| 200903 | 999.999.999.995 | 5 |
| 200903 | 999.999.999.994 | 4 |
| 200903 | 999.999.999.993 | 3 |
| 200903 | 999.999.999.992 | 2 |
+--------+-----------------+------+

现在显示每月前三个 IP 地址:

SELECT m1.month, m1.ip_address, m1.hits
FROM my_data_per_month m1
LEFT OUTER JOIN my_data_per_month m2
ON (m1.month = m2.month AND m1.hits < m2.hits)
GROUP BY m1.month, m1.ip_address
HAVING COUNT(*) < 3
ORDER BY m1.month ASC, m1.hits DESC;

+--------+-----------------+------+
| month | ip_address | hits |
+--------+-----------------+------+
| 200901 | 999.999.999.999 | 8 |
| 200901 | 999.999.999.998 | 6 |
| 200901 | 999.999.999.997 | 5 |
| 200902 | 999.999.999.998 | 8 |
| 200902 | 999.999.999.997 | 6 |
| 200902 | 999.999.999.996 | 5 |
| 200903 | 999.999.999.997 | 8 |
| 200903 | 999.999.999.996 | 6 |
| 200903 | 999.999.999.995 | 5 |
+--------+-----------------+------+

关于mysql - 按 MySQL 中的前 N ​​个分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1358958/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com