首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >迭代日期Mysql循环

迭代日期Mysql循环
EN

Stack Overflow用户
提问于 2019-04-20 21:05:56
回答 1查看 2.5K关注 0票数 1

我编写了一个存储过程,每周迭代一次,持续三年。但是它不起作用,并返回一条模糊的错误消息。

#1064 -您的SQL语法有错误;请检查与您的MariaDB服务器版本对应的手册,以获得在第18行附近使用的正确语法。

代码语言:javascript
运行
复制
DELIMITER $$
CREATE PROCEDURE loop_three_years()
BEGIN
    declare y INT default 2016;
    declare m int default 4;
    declare d int default 20;
    WHILE y <= 2019 DO
        WHILE YEARWEEK(concat(y, '-', m, '-', d)) <= 53 DO
            WHILE m < 12 DO
                WHILE (m = 2 and d <= 29) OR (d <=30 and m in(4, 6,9,11)) OR ( m in(1,3,5,7,8,10,12) AND d <= 31) DO
                    set d = d + 7;
                    SELECT YEARWEEK(concat(y, '-', m, '-', d));
                END WHILE;
                set d=1;
        END WHILE;
        set m = 1;
        SET y = y + 1;
    END WHILE;
END
$$

当我使用它作为最小的部件时,它们可以工作,所以我不知道我的重新组装有什么问题。也不确定是否有更好的方法来做这件事。( select只是用于测试,当我使用真正的代码时,它将是一个insert

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-21 01:10:43

Slightly Altered from a previous solution

您可以使用系统中的任何其他表构建自己的动态日历/列表,这些表至少具有与伪造行号相同的记录。下面的查询将使用MySQL @变量,这些变量的工作方式类似于内联程序和声明。我可以从给定的日期开始.如你的2016-04-20,然后每次迭代通过,增加1周使用日期为基础的功能。不需要我知道或关心有多少天有28,29(闰年),30或31天。

下面的"AnyTableThatHasAtLeast156Records“表引用就是..。数据库中任何至少有156项记录的表格(每年52周,3年)

代码语言:javascript
运行
复制
select
      YEARWEEK( @startDate ) WeekNum,
      @startDate as StartOfWeek,              
      @startDate := date_add( @startDate, interval 1 week ) EndOfWeek
   from 
      ( select @startDate := '2016-04-20') sqlv,
      AnyTableThatHasAtLeast156Records
   limit
      156 

这将给您提供156个记录的列表(如果您的“任意表…”)一次有156个记录。如果您需要将此连接到其他事务表,则可以通过将上面的连接表设置为join表来实现。这里的好处,因为我包括了开始日期和周末,这些可以成为您加入表的一部分。

例如,on

代码语言:javascript
运行
复制
record   WeekNum   StartOfWeek   EndOfWeek
1        ??        2016-04-20    2016-04-27
2        ??        2016-04-27    2016-05-04
3        ??        2016-05-04    2016-05-11
4        ??        2016-04-11    2016-05-18... etc

通过在起点上增加一个星期,你可以看到它会做Ex:星期一到星期一。下面的联接条件比EndOfWeek小。这将说明到但不包括截止日期的任何交易.例如2016-04-26 11:59:59下午(因此少于2016-04-27,因为04/27是下周交易周期的开始)

代码语言:javascript
运行
复制
select
      Cal.WeekNum,
      YT.YourColumns
   from
      YourTransactionTable YT
         JOIN ( aboveCalendarQuery ) Cal
            on YT.TransactionDate >= Cal.StartOfWeek
            AND YT.TransactionDate < Cal.EndOfWeek
   where
      whatever else

您甚至可以按照WeekNum这样的方式对group ()执行sum(),如果这是您的意愿的话。

希望这是一种更准确、更有效的方法来构建您的日历以运行并链接到事务(如果您需要的话)。

来自评论的回应。

您可以通过连接到一个(选择1个联合,选择2个联合…)选择156 ),但是你的选择。"AnyTable…“的唯一原因我确信有任何合理的数据库与交易,你会有156条记录,或更容易。它的唯一目的是只允许一行循环遍历迭代,以动态创建行。

也比你一开始遇到的循环机制更健全。这没有什么错,尤其是学习的目的,但如果更有效的方法,这不是更有意义吗?

/评论中的反馈

我不太清楚你想要插入的另一张桌子,但是是的,你可以用它来做所有的3000件事情。提供更多你想做的事我可以调整.在一般的时间里,像这样的.

代码语言:javascript
运行
复制
insert into YourOtherTable
(   someField,
    AnotherField,
    WeekNum 
)
select
      x.someField,
      x.AnotherField,
      z.WeekNum
   from
      Your3000ThingTable x
         JOIN (select
                     YEARWEEK( @startDate ) WeekNum,
                     @startDate as StartOfWeek,              
                     @startDate := date_add( @startDate, interval 1 week ) EndOfWeek
                  from 
                     ( select @startDate := '2016-04-20') sqlv,
                     AnyTableThatHasAtLeast156Records
                  limit
                     156 ) z
            on 1=1
   where
      x.SomeCodition...

通过加入1=1上156个记录的选择(总是正确的),它将为Your3000ThingTable中的任何记录返回156个条目。因此,如果您有一个库存项目表

代码语言:javascript
运行
复制
Item  Name
1     Thing1
2     Thing2
3     Thing3

您的最后插入将是

代码语言:javascript
运行
复制
Item   Name     WeekNum
1      Thing1   1
1      Thing1   2
1      Thing1   ...
1      Thing1   156
2      Thing2   1
2      Thing2   2
2      Thing2   ...
2      Thing2   156
3      Thing3   1
3      Thing3   2
3      Thing3   ...
3      Thing3   156

要预先确认您认为会发生什么,只需在1=1上尝试select/join,您将看到查询将插入到目标表中的所有记录。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55777728

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档