每两周对mysql记录进行分组

时间:2011-05-29 03:57:06

标签: mysql

我想在其时间戳字段Fortnightly上对记录进行分组。我现在每周都在做,但我也希望它每两周一次。我怎么做 ?是否有一种特定的方法来实现这一点,比如我们如何使用WEEK('timestamp','%d-%m-%Y')功能按周分组?

在下面的图片中,您可以看到日期21和14出现两周10.有任何建议吗?

4 个答案:

答案 0 :(得分:5)

week()获取结果并除以2,转换为整数(向上或向下)。因为一年的第一周是第1周(取决于模式week()使用)并且您可能希望第1周和第2周都变为两周1,以便第0周变为两周0,我们将使用{{ 1}}:

ceil()

参考:week() and its modes

修改:获取两周的最后一天......

没有内置函数可以从周数中获取任何日期。多么令人讨厌。

由于您在两周内聚合和分组(因此结果行可能在几十行中),我通常首先考虑在消费结果的客户端代码中计算这样的填充值,但事实证明它实际上更容易由于访问原始时间戳,在数据库中执行此操作,即使它很难看。

您所要做的就是从原始时间戳计算周末,但如果是从第一周开始,您还需要再增加7天,以便从每周的第二周开始计算周末两星期。 (基于this article。)我还添加了年份,以防万一。并且它还假设星期日是一周的第一天(但是检查你的MySQL实例的select sum(amount) as amountSum, ceil(week(myTimestamp)/2) as fortnight from myTable group by fortnight order by fortnight; 对照default_week_format的表进行仔细检查。

week()

我希望有效或足够接近。我没有用很多数据测试它。

答案 1 :(得分:1)

SELECT CEILING(DATEPART(wk,Timestamp)/2.0) AS 'Fortnight'
FROM mytable
GROUP BY CEILING(DATEPART(wk,Timestamp)/2.0)
ORDER BY CEILING(DATEPART(wk,DateKey)/2.0);

使用DATEPART函数,wk给出一年中的周数。

当我们GROUP BY DATEPART(wk,Timestamp)/2时,我们每两周进行一次分组。

要获得更准确的答案,可以使用CEILING()ROUND()

FYI DATEPART(wk,Timestamp)/ 2范围从0到26因此
DATEPART(DATEPART(wk,Timestamp)/ 2)范围从0到26 但 CEILING(DATEPART(wk,Timestamp)/2.0)范围是1到27

答案 2 :(得分:0)

测量从任意开始日期开始的天数,然后除以14.以下是Redshift PSQL中的实现:

SELECT COUNT(1)
  ,DATEDIFF('day', '5-28-2012', hour)/14 as fortnight,
  ,DATEADD('day', 14 * (DATEDIFF('day', '5-28-2012', hour)/14), '5-28-2012') as start_of_fortnight
GROUP BY 1
ORDER BY 1

week()函数可能会非常复杂 - 我会避免它。

答案 3 :(得分:0)

我无法在网上找到一个好的解决方案,所以我想我会分享我的。

基本上我试图做的是写一个查询,该查询返回了一个企业的两周成本明细,其中支付周在周四之间。

我在工作场所看到的以前的解决方案是生成一个表,该表存储两周的数字以及该两周的日期范围,允许用户将两周的信息加入基表。

我不想为此创建一个表,所以我写了下面的查询:

SELECT
ROUND(SUM(a.logged/60),2) as logged,
DATE_ADD(DATE_ADD(CONCAT(YEAR(a.start),'-01-01'),INTERVAL (2+a.ft) WEEK), INTERVAL (3-WEEKDAY(CONCAT(YEAR(a.start),'-01-01'))) DAY) as fortnight_end

FROM (
    SELECT
        TIMESTAMPDIFF(MINUTE, a.start, a.finish) as logged,
        a.start,
        CASE WHEN week(a.start)%2=1 AND weekday(a.start) IN (5,4,3) THEN week(a.start)
            WHEN week(a.start)%2=1 AND weekday(a.start) IN (0,1,2,6) THEN week(a.start)-2
            WHEN week(a.start)%2=0 THEN week(a.start)-1
            ELSE week(a.start)
            END AS fortnight    

        FROM table_name as a

) as a

GROUP BY a.fortnight

ORDER BY end desc

内部查询根据基表中的日期分配两周的数字。在这里,它被设计为从星期四开始到星期三结束的工作。要更改两周的开始/结束日期,您只需要调整CASE语句的IN()子句中的WEEKDAY索引。

外部查询然后使用两周数来确定两周的最终日期。要将星期四的结束日期从星期四改为另一天,您只需要更改它所说的#3; 3-WEEKDAY"的数字3。请注意,此日期将从组中排除。

同样重要的是要注意,上述代码旨在与业务的付费周期同步,在这种情况下,结果是在WEEK函数返回的奇数周内循环。如果您的周期要在几周后开始,请将%1更改为%0'反之亦然。

我希望这能帮助那些与我相似的人,我很惊讶在任何地方都看不到这种形式的解决方案。