【问题标题】:Add a week to an SQL value stored in YYYMMDD format将一周添加到以 YYYYMMDD 格式存储的 SQL 值
【发布时间】:2017-09-07 11:24:55
【问题描述】:

我目前将 WordPress 高级自定义字段日期作为时间戳存储在我的数据库中,但由于新插件的要求,我现在必须将它们存储为 YYYYMMDD 格式。

我有一个 chronjob 设置为每晚运行,它为我网站上的每个每周事件增加一周 (604800),其中“event_date”小于当前的 UNIX_TIMESTAMP。这将重新发布下一周的活动。

我假设我需要将 YYYYMMDD 格式转换为时间戳,添加 604800 然后将其转换回来,但真的不知道如何去做(SQL 不是我的强项!)

当前的SQL我必须在每个类别ID为29(每周)的帖子的时间戳中添加604800,在类别ID为19(每两周)中添加1209600如下...

下面的代码已经更新并且正在运行!

UPDATE wp_postmeta rh

INNER JOIN (
    SELECT ID, wt.term_id
    FROM wp_terms wt
    INNER JOIN wp_term_taxonomy wtt ON wt.term_id = wtt.term_id
    INNER JOIN wp_term_relationships wpr ON wpr.term_taxonomy_id = wtt.term_taxonomy_id
    INNER JOIN wp_posts ON ID = wpr.object_id 
    WHERE taxonomy = 'category'
      AND (wt.term_id=32)
      AND post_type = 'post'
    ) t ON rh.post_id = t.ID
 SET rh.meta_value = CASE 
   WHEN t.term_id = 32 
   THEN DATE_FORMAT(STR_TO_DATE(rh.meta_value, '%Y%m%d') + INTERVAL 1 WEEK, '%Y%m%d')
   ELSE rh.meta_value END

WHERE rh.meta_key = 'event_date' AND rh.meta_value < UNIX_TIMESTAMP();

有没有人能提出为这些现在以 YYYYMMDD 格式存储的事件添加一周(或两周)的最佳方式?

这需要存储在 PHP 脚本中,因此我可以设置一个 chronjob 以每晚自动执行和更新它。

提前致谢, 标记。

【问题讨论】:

  • event_date 数据类型是 varchar ?
  • event_date的meta_key的meta_value存储为longtext
  • 是的,这是wp_postmeta 键/值存储的典型问题。这些值都是文本。

标签: php mysql sql wordpress datetime


【解决方案1】:

如果您有类似 20170901 的内容,并且您想为其添加一周,请在 SQL 中尝试此操作。

 DATE_FORMAT(STR_TO_DATE(date_text_col, '%Y%m%d') + INTERVAL 1 WEEK, '%Y%m%d')

这会将您的文本转换为DATETIME。然后它将添加一周。然后它会将其转换回文本。

这应该适用于任何文本数据类型(CLOB、VARCHAR、CHAR)。

该日期计算的结果应直接放入列中,而不是添加到列中。像这样的表达式应该可以做到。

SET rh.meta_value = CASE 
       WHEN t.term_id = 32 
       THEN DATE_FORMAT(STR_TO_DATE(rh.meta_value, '%Y%m%d') + INTERVAL 1 WEEK, '%Y%m%d')
       ELSE rh.meta_value END

如果您使用rh.meta_value = rh.meta_value + (some date),则将日期添加到自身,就好像它是一个数字一样,这是没有意义的。

wp_postmeta 的布局与 MySQL 自动将文本强制转换为数字相结合,会使这类事情变得非常混乱。

【讨论】:

  • 感谢您的回复。我已经尝试修改上面的 SQL 查询以合并您的代码,但不确定我是否正确地遵循了它。它更新了值“event_date”,但一周没有添加……它从 20170906 更改为 40341819! SET rh.meta_value = rh.meta_value + CASE WHEN t.term_id = 32 THEN DATE_FORMAT(STR_TO_DATE(rh.meta_value, '%Y%m%d') + INTERVAL 1 WEEK, '%Y%m%d') END(我已将 term_id(类别)更改为 32,并将我的一篇帖子赋予该类别,因此它仅更新该类别以进行测试)
  • 请看我的编辑。 4034181920170906 + 20170913
  • 找到伙伴,完美运行!标记为已回答,非常感谢您的帮助!
【解决方案2】:

使用PHP,很简单,从你的数据库中选择行,循环,然后更新:

<?php

$date = new DateTime('2014-09-18 00:00:00'); // populate with row value!
$date->modify('+1 week');
echo $date->format('Ymd');

这将输出20140925。然后更新你的行。看这里https://3v4l.org/5e8fg

另外,请查看DateTime::createFromFormat() http://php.net/manual/en/datetime.createfromformat.php 以不同的格式实例化 DateTime。

【讨论】:

  • 感谢您的回复。我需要能够更新存储在数据库中的值,而不仅仅是在前端显示值 + 1 周
  • 是的,很好地获取行,操纵日期时间,而不是回显它,在UPDATE 语句中使用$date-&gt;format()
【解决方案3】:

这主要是评论 - 但有点长。

但由于新插件的要求,我现在必须将它们存储为 YYYYMMDD 格式。

鉴于它们以日期属性类型存储为 YYYMMDD,我猜您的意思是您认为您需要使用整数或字符数据类型。在这种情况下...... OMG,WTF?

  1. 正如您已经发现的那样,这使得维护数据很多变得更加困难

  2. 您有要更新的现有数据意味着您系统中的其他东西正在使用此属性 - 您确定使用此属性的其他所有东西都将被淘汰吗?

在检查Wordpress site 时,我发现问题实际上出在 Wordpress 中,它使用了非常讨厌的 EAV 表设计。虽然我不希望设计者期望数据会以这个插件/您的​​应用程序的方式使用。

如果数据格式正确(并且比您当前添加秒数的方法更正确),DBMS 可以进行数学运算,因此您只需将存储的数据转换为日期,然后再转换回来以进行写入:

UPDATE wp_postmeta rh
INNER JOIN (....) t ON rh.post_id = t.ID
SET rh.meta_value = DATE_FORMAT(
      STR_TO_DATE(rh.meta_value, '%Y%m%d') + INTERVAL 
      CASE WHEN t.term_id = 29 THEN 7 DAY
           WHEN t.term_id = 19 THEN 14 DAY 
      END, '%Y%m%d')

【讨论】:

  • 这看起来很有希望,但没有奏效,但离我们不远了!我已经更新了原始代码以纳入您的建议(删除了每两周一次的部分以尝试简化一点并将类别 ID 更改为 32,因此它不会影响我的所有帖子)。我会继续摆弄,但如果你能看到任何明显的东西,任何建议都会非常受欢迎。
【解决方案4】:

如果你有一个列存储作为 varchar,你可以使用 date_add 和 str_to_date

 select  DATE_ADD(str_to_date(your_column, '%Y%m%d'),INTERVAL 1 WEEK)
 from my_table

【讨论】:

  • event_date 的 meta_key 的 meta_value 存储为长文本。这还能用吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-03
  • 1970-01-01
  • 1970-01-01
  • 2017-05-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多