为每个月出现 n 次的特定列选择具有相似值的行

Selecting rows which have a similar value for a particular column which occurs n times each month

我有一个包含多个列的数据库,我从中创建了这个视图,其中我有多个类似于下面显示的行。该数据适用于从 2009 年到 2010 年每个月的每一天以及给定的 5 个名称的整个月。我必须获取每月出现类别 'Super' 超过 5 次的 'Name',并按每个月分别列出它们。该视图包含所有月份的数据。

Name  Dates      Category
--------------------------------
PAT  2009-01-01 Super
YAT  2009-01-01 No 
ROT  2009-01-01 No 
SUP  2009-01-01 Super 
ANT  2009-01-01 Super 

我尝试使用

计算 MySQL 中的名称
SELECT `NAME`,`DATES` 
FROM (
        SELECT `NAME`, `CATEGORY`,MONTH(`DATES`)
        FROM VIEW
        GROUP BY `NAME`, `CATEGORY`,MONTH(`DATES`)
        HAVING COUNT(`CATEGORY`)>5 
    ) a
GROUP BY `NAME`
HAVING count(`CATEGORY`)>5;

但它没有 return 任何行。

您正在尝试将行分组为月份。执行此操作的最佳方法是从一个表达式开始,该表达式将采用任何日期并将其转换为该日期所在月份的第一天。那表情就是。

 DATE(DATE_FORMAT(dates, '%Y-%m-01'))

接下来,在带有 GROUP BY 子句的查询中使用此表达式。

SELECT NAME, CATEGORY, 
       DATE(DATE_FORMAT(DATES, '%Y-%m-01')) DATES
  FROM VIEW
 GROUP BY NAME, CATEGORY, DATE(DATE_FORMAT(DATES, '%Y-%m-01'))
HAVING COUNT(*) > 5

这将生成出现次数超过五次的所有名称/类别/月份组合。

我想这就是你想要的。但也许您想要 all 某个名称的超级类别出现超过五次的任何月份中列出的每月项目。为此,我们首先编写一个子查询来获取这些日期的列表:

            SELECT DATE(DATE_FORMAT(DATES, '%Y-%m-01')) DATES
              FROM VIEW
             WHERE CATEGORY = 'Super'
             GROUP BY NAME, DATE(DATE_FORMAT(DATES, '%Y-%m-01'))
            HAVING COUNT(*) > 5

然后我们写一个主查询来获取所有的数据

SELECT DISTINCT
       NAME, CATEGORY, 
       DATE(DATE_FORMAT(DATES, '%Y-%m-01')) DATES
  FROM VIEW
 WHERE DATE(DATE_FORMAT(DATES, '%Y-%m-01')) IN
        (
            SELECT DATE(DATE_FORMAT(DATES, '%Y-%m-01')) DATES
              FROM VIEW
             WHERE CATEGORY = 'Super'
             GROUP BY NAME, DATE(DATE_FORMAT(DATES, '%Y-%m-01'))
            HAVING COUNT(*) > 5
        )

让这类事情起作用的诀窍是选择正确的日期算术表达式以在 GROUP BY 子句中使用。 DAY()MONTH()YEAR() 等函数出奇地难以正确使用,因此我认为您可能会发现 DATE(DATE_FORMAT(dates, '%Y-%m-01')) 更可靠。