English 中文(简体)
每两周对mysql记录进行分组
原标题:Grouping mysql records fortnightly
  • 时间:2011-05-29 03:57:06
  •  标签:
  • mysql

我想在其时间戳字段“每两周”中对记录进行分组。我现在每周一次,但我也希望每两周一次。我该怎么做?有没有具体的方法可以做到这一点,比如我们如何使用WEEK(时间戳,%d-%m-%Y)函数按周分组?

在下图中,您可以看到日期21和14将持续两周10。有什么建议吗?

最佳回答

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

select sum(amount) as amountSum, ceil(week(myTimestamp)/2) as fortnight
  from myTable
  group by fortnight
  order by fortnight;

参考:week()及其模式

编辑:在两周的最后一天。。。

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

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

你所要做的就是根据原始时间戳计算周末,但如果是从第一周算起,你还必须再加7天,这样你才能从每两周的第二周算起周末。(基于这篇文章。)我还添加了年份,以防万一。它还假设周日是一周的第一天(但请对照week()的表检查MySQL实例的default_week_format以进行双重检查)。

select sum(amount) as amountSum, year(myTimestamp) as yr, ceil(week(myTimestamp)/2) as fortnight,
  date_add(myTimestamp, interval (7 - dayofweek(myTimestamp)) + ((week(mytimestamp) % 2) * 7) day) as endoffortnight
  from myTable
  group by yr, fortnight
  order by yr, fortnight;

我希望这是有效的或足够接近。我没有用太多数据来测试它。

问题回答
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将给出一年中的周数。

当我们<code>GROUP BY DATEPART(wk,Timestamp)/2</code>时,我们是按每两周分组一次。

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

FYI DATEPART(wk,Timestamp)/2 range is from 0 to 26 therefore
DATEPART(DATEPART(wk,Timestamp)/2) range is from 0 to 26 but CEILING(DATEPART(wk,Timestamp)/2.0) range is 1 to 27

测量任意开始日期的天数,然后除以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()函数可能会变得相当复杂——我会避免它。

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

基本上,我想做的是写一个查询,返回企业每两周的成本明细,其中发薪周在星期四到星期四之间。

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

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

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周”即可。请注意,此日期已被排除在组之外。

同样需要注意的是,上面的代码是为了与企业的支付周期同步而设计的,在这种情况下,支付周期是在WEEK函数返回的奇数周进行的。如果您的周期从偶数周开始,请将%1秒更改为%0秒,反之亦然。

我希望这能帮助到一个和我处境相似的人,我很惊讶在任何地方都没有看到这种表格的解决方案。





相关问题
SQL SubQuery getting particular column

I noticed that there were some threads with similar questions, and I did look through them but did not really get a convincing answer. Here s my question: The subquery below returns a Table with 3 ...

please can anyone check this while loop and if condition

<?php $con=mysql_connect("localhost","mts","mts"); if(!con) { die( unable to connect . mysql_error()); } mysql_select_db("mts",$con); /* date_default_timezone_set ("Asia/Calcutta"); $date = ...

php return a specific row from query

Is it possible in php to return a specific row of data from a mysql query? None of the fetch statements that I ve found return a 2 dimensional array to access specific rows. I want to be able to ...

Character Encodings in PHP and MySQL

Our website was developed with a meta tag set to... <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> This works fine for M-dashes and special quotes, etc. However, I ...

Pagination Strategies for Complex (slow) Datasets

What are some of the strategies being used for pagination of data sets that involve complex queries? count(*) takes ~1.5 sec so we don t want to hit the DB for every page view. Currently there are ~...

Averaging a total in mySQL

My table looks like person_id | car_id | miles ------------------------------ 1 | 1 | 100 1 | 2 | 200 2 | 3 | 1000 2 | 4 | 500 I need to ...

热门标签