MySQL group by like 语句?

mer*_*lin 5 mysql group-by like

我需要从我们的 MySQL-DB 中获取一些统计信息,并想知道是否有更快的方法来做到这一点。

基本上,在按属性进行分隔之前,我需要有关任何给定月份的用户注册信息。

例如:

SELECT count(*) AS c  
FROM `users` 
WHERE `date_created` LIKE '2015-10%' 
  AND `country` = 'DE'
Run Code Online (Sandbox Code Playgroud)

这将返回 2015 年 10 月的数字。如何更改此语句以在一个语句中返回所有月份的结果?

我也有兴趣添加类似AND confirmed = 1单独的结果。

仅使用一个 MySQL 语句就可以做到这一点吗?

Ric*_*mes 6

需要做两件事才能让它运行得更快:

获取合适的索引

没有confirmed = 1,你需要

INDEX(country, date_created)
Run Code Online (Sandbox Code Playgroud)

有了它,你需要

INDEX(country, confirmed, date_created)
Run Code Online (Sandbox Code Playgroud)

避免在函数中隐藏日期

LIKE '2015-10%'不能在 上使用索引date_created,也不能MONTH(date_created),所以让我们重新制定查询:

WHERE date_created >= '2015-10-01'
  AND date_created  < '2015-10-01' + INTERVAL 1 MONTH
  AND confirmed = 1   -- add this if you want to limit to confirmed rows
Run Code Online (Sandbox Code Playgroud)

(这假设它date_created是一个DATETIMEorTIMESTAMP数据类型。)

所有月份

这个查询仍然可以使用我建议的两个索引,但是,它不一定会使用该date_created部分。

SELECT LEFT(date_created, 7) AS YYYY_MM,
       COUNT(*) AS ct
    FROM tbl
    WHERE country = 'DE'
      AND confirmed = 1   -- if you want this
    GROUP BY YYYY_MM;
Run Code Online (Sandbox Code Playgroud)

注意事项 country_code

定义模式(请提供SHOW CREATE TABLE)的一个常见错误是将其定义为CHAR(2)并默认为 utf8。这导致使用 6 个字节,而 2 个就足够了。更改为CHAR(2) CHARACTER SET ascii


dno*_*eth 1

SELECT
   EXTRACT(YEAR FROM date_created) AS yr,   -- for each year
   EXTRACT(MONTH FROM date_created) AS mth, -- & month combination 
   count(*) AS c,                                 -- count all rows 
   SUM(CASE WHEN confirmed = 1 THEN 1 ELSE 0 END) -- count only confirmed rows 
FROM users
WHERE country = 'DE'
GROUP BY yr, mth
Run Code Online (Sandbox Code Playgroud)