MySQL 按日期查询分组(12 小时间隔)

MySQL Query Group By Date (12 hours Interval)

我写了一个 sql 查询来获取在一段时间内创建的用于绘制图表(grafana 或图表 js)的用户数量,我的 sql 查询是

 SELECT
  date(user.created_date) as "time",
  count(distinct user.id) as Number Of User,
  status as status
FROM user
WHERE
  created_date >= FROM_UNIXTIME(1649635200) AND 
  created_date < FROM_UNIXTIME(1649894399)
GROUP BY user.status, date(user.created_date)
ORDER BY date(user.created_date)

在此查询中,创建日期是从前端动态传递的, 现在我得到的结果是,

现在,每当我 select 最近 24 hours/12 小时的日期过滤器时,有些结果不存在,

有什么方法可以修改我的 sql 查询以按 created_date 分组,间隔为 12 小时 例如,现在查询结果是 11/04/2022 - 5 Users(Application Created) 我想要这样的查询结果 11/04/2022 00:00:00 2 - 2 users created 11/04/2022 12:00:00 - 创建了 3 个用户

在 grafana 中有一个字段 $__timeFrom()$__timeTo() 在此基础上我重写了我的查询:

SELECT
  (CASE 
    WHEN HOUR(TIMEDIFF($__timeFrom(), $__timeTo())) <= 24
    THEN user.created_date
    ELSE date(user.created_date) end) AS "time",
  count(distinct user.id) as Users,
FROM user
WHERE
  user.created_date >= $__timeFrom() AND 
  user.created_date < $__timeTo() AND
GROUP BY CASE
  when HOUR(TIMEDIFF($__timeFrom(), $__timeTo())) <= 24
  then user.created_date
  else date(created_date) end
ORDER BY CASE
  when HOUR(TIMEDIFF($__timeFrom(), $__timeTo())) <= 24
  then user.created_date
  else date(created_date) end;

如果您在 GROUP BY 中使用此表达式,您将获得 12 小时的分组。

DATE(created_date) + INTERVAL (HOUR(created_date) - HOUR(created_date) MOD 12) HOUR

如果你有 priv,你可以声明一个存储函数以使其更易于阅读。

DELIMITER $$
DROP FUNCTION IF EXISTS TRUNC_HALFDAY$$
CREATE
  FUNCTION TRUNC_HALFDAY(datestamp DATETIME)
  RETURNS DATETIME DETERMINISTIC NO SQL
  COMMENT 'truncate to 12 hour boundary. Returns the nearest
           preceding half-day (noon, or midnight)'
  RETURN DATE(datestamp) +
                INTERVAL (HOUR(datestamp) -
                          HOUR(datestamp) MOD 12) HOUR$$
DELIMITER ;

那你可以做

SELECT
  TRUNC_HALFDAY(user.created_date) as "time",
  count(distinct user.id) as Number Of User,
  status as status
FROM user
WHERE
  created_date >= whatever AND 
  created_date < whatever
GROUP BY user.status, TRUNC_HALFDAY(user.created_date)
ORDER BY TRUNC_HALFDAY(user.created_date)

即使该函数在您的查询中出现了三次,因为它被声明为 DETERMINISTIC 它每行只被调用一次。

更完整的文章 here