首页 > 解决方案 > 如何在 SQL 中使用过去 7 天的“groupby”而不是“真正的一周”

问题描述

我有一个 SQL PB。我需要按“滑动周”对一些账单进行分组(我的客户需要全年过去的 7 天,所以从当天开始),但我一无所获。我很确定我只是没有好的关键字,但我仍在搜索 2 天。所以我在下面有我的 sql 请求,它可以正常使用 WEEK:

SELECT 
  WEEK(billing_date) as billed_week
, ROUND(sum(price) * 1.1, 2) as billed_amount
, billing_date as billing_date 
FROM bills 
JOIN missions m 
  ON bills.mission_id = m.id 
WHERE customer_id = $customer_id 
  AND status = 2 AND YEAR(billing_date) = YEAR(CURRENT_DATE) 
GROUP BY week(billing_date)

例如,是否有更新 WEEK 的函数参数?

标签: sqlgroup-by

解决方案


您可以通过WEEK根据今天日期的星期几将传递的日期转换为您想要的结果。这将导致WEEK返回一个在一周中的那一天发生变化的值。鉴于您使用的是 PHP,我将假设这是 MySQL,在这种情况下,您将查询重写为:

SELECT 
  WEEK(billing_date - INTERVAL DAYOFWEEK(billing_date) DAY, 0) as billed_week
, ROUND(sum(price) * 1.1, 2) as billed_amount
, billing_date as billing_date 
FROM bills 
JOIN missions m 
  ON bills.mission_id = m.id 
WHERE customer_id = $customer_id 
  AND status = 2 AND YEAR(billing_date) = YEAR(CURRENT_DATE) 
GROUP BY WEEK(billing_date - INTERVAL DAYOFWEEK(billing_date) DAY, 0)

请注意,我将0其用作函数的mode参数,WEEK以便它返回的结果基于星期天的开始,这是对应于返回的最小值的星期几DAYOFWEEK

另请注意,正如其他人在评论中指出的那样,您不应该在查询中直接包含 PHP 变量,因为这会使您容易受到SQL 注入的攻击。相反,为您需要的变量使用带有占位符的准备好的语句。例如,像这样的东西(假设MySQLi接口带有连接$conn):

$sql = 'SELECT 
      WEEK(billing_date - INTERVAL DAYOFWEEK(billing_date) DAY, 0) as billed_week
    , ROUND(sum(price) * 1.1, 2) as billed_amount
    , billing_date as billing_date 
    FROM bills 
    JOIN missions m 
      ON bills.mission_id = m.id 
    WHERE customer_id = ? 
      AND status = 2 AND YEAR(billing_date) = YEAR(CURRENT_DATE) 
    GROUP BY WEEK(billing_date - INTERVAL DAYOFWEEK(billing_date) DAY, 0)';
$stmt = $conn->prepare($sql);
$stmt->bind_param('i', $customer_id);
$stmt->execute();

推荐阅读