文章 查看内容

在数据集的模型结构sql里,通过判断时间来运行不同的取数sql ...

在数据集的模型结构sql里,通过判断时间来运行不同的取数sql ...

9 0 函数专题 2025-4-1 16:26 发布者: 观小益

有些场景希望不同日期时间增量获取不同的数据,比如 想要早上9:30更新昨天的数据,凌晨更新全月的数据,另外每月1-9号的凌晨要更新上个月和本月的数据。但是数据集定时更新设置不支持这样的判断设置,就需要借助模 ...

一、背景

有些场景希望不同日期时间增量获取不同的数据,比如 想要早上9:30更新昨天的数据,凌晨更新全月的数据,另外每月1-9号的凌晨要更新上个月和本月的数据。但是数据集定时更新设置不支持这样的判断设置,就需要借助模型结构sql条件判断实现。

二、案例

以 resource_role_rel 表为例,业务需求要求根据当前日期和时间动态动态调整增量更新sql,以获取符合特定时间范围的记录。具体需求如下:


  1. 每月 1 - 9 号早上 9 点半前,查询创建时间大于上月第一天的记录。
  2. 日期大于 9 号,早上 9 点半之前,查询创建时间大于本月第一天的记录。
  3. 早上 9 点半之后,查询创建时间等于昨天的记录。
三、实现思路
为了实现上述需求,我们将使用 SQL 语句结合 MySQL 提供的日期和时间函数来动态生成查询条件。主要思路是根据当前日期和时间进行条件判断,然后使用 OR 逻辑将不同的条件组合起来,确保满足任意一个条件的记录都能被查询出来。
SELECT *
FROM `resource_role_rel`
WHERE 
    (
        -- 每月 1 - 9 号早上 9 点半前,创建时间大于上月第一天
        DAY(NOW()) BETWEEN 1 AND 9 
        AND (HOUR(NOW()) < 9 OR (HOUR(NOW()) = 9 AND MINUTE(NOW()) < 30))
        AND `ctime` > DATE_SUB(DATE_FORMAT(CURDATE(), '%Y-%m-01'), INTERVAL 1 MONTH)
    )
    OR (
        -- 日期大于 9 号,早上 9 点半之前,创建时间大于本月第一天
        DAY(NOW()) > 9 
        AND (HOUR(NOW()) < 9 OR (HOUR(NOW()) = 9 AND MINUTE(NOW()) < 30))
        AND `ctime` > DATE_FORMAT(CURDATE(), '%Y-%m-01')
    )
    OR (
        -- 早上 9 点半之后,创建时间等于昨天
        (HOUR(NOW()) > 9 OR (HOUR(NOW()) = 9 AND MINUTE(NOW()) >= 30))
        AND `ctime` >= CURDATE() - INTERVAL 1 DAY AND `ctime` < CURDATE()
    );

四、代码详细解释

1. 第一个条件块

(
    DAY(NOW()) BETWEEN 1 AND 9 
    AND (HOUR(NOW()) < 9 OR (HOUR(NOW()) = 9 AND MINUTE(NOW()) < 30))
    AND `ctime` > DATE_SUB(DATE_FORMAT(CURDATE(), '%Y-%m-01'), INTERVAL 1 MONTH)
)
)
  • DAY(NOW()) BETWEEN 1 AND 9:使用 DAY(NOW()) 函数获取当前日期是当月的第几天,通过 BETWEEN 操作符判断是否在 1 到 9 之间,确保只在每月 1 - 9 号进行该条件的查询。
  • (HOUR(NOW()) < 9 OR (HOUR(NOW()) = 9 AND MINUTE(NOW()) < 30)):通过 HOUR(NOW()) 和 MINUTE(NOW()) 函数分别获取当前时间的小时和分钟,判断当前时间是否在早上 9 点半之前。
  • ctime > DATE_SUB(DATE_FORMAT(CURDATE(), '%Y-%m-01'), INTERVAL 1 MONTH)DATE_FORMAT(CURDATE(), '%Y-%m-01') 将当前日期格式化为当前月的第一天,DATE_SUB(..., INTERVAL 1 MONTH) 从当前月第一天减去一个月得到上个月的第一天,最后判断 ctime 字段是否大于上个月的第一天。

2. 第二个条件块

(
    DAY(NOW()) > 9 
    AND (HOUR(NOW()) < 9 OR (HOUR(NOW()) = 9 AND MINUTE(NOW()) < 30))
    AND `ctime` > DATE_FORMAT(CURDATE(), '%Y-%m-01')
)

    • DAY(NOW()) > 9:判断当前日期是否大于 9 号。
    • (HOUR(NOW()) < 9 OR (HOUR(NOW()) = 9 AND MINUTE(NOW()) < 30)):同样判断当前时间是否在早上 9 点半之前。
    • ctime > DATE_FORMAT(CURDATE(), '%Y-%m-01'):判断 ctime 字段是否大于本月第一天。

    3. 第三个条件块

    (
        (HOUR(NOW()) > 9 OR (HOUR(NOW()) = 9 AND MINUTE(NOW()) >= 30))
        AND `ctime` >= CURDATE() - INTERVAL 1 DAY AND `ctime` < CURDATE()
    )
    

      • (HOUR(NOW()) > 9 OR (HOUR(NOW()) = 9 AND MINUTE(NOW()) >= 30)):判断当前时间是否在早上 9 点半之后。
      • ctime >= CURDATE() - INTERVAL 1 DAY AND ctime < CURDATE()CURDATE() - INTERVAL 1 DAY 得到昨天的日期,通过该条件判断 ctime 字段是否等于昨天。

      4. OR 逻辑

      三个条件块通过 OR 连接,只要满足其中一个条件的记录就会被查询出来,从而实现了根据不同日期和时间动态筛选数据更新数据集的需求。

      五、注意事项

      1. 数据库时间设置:确保 MySQL 服务器的时间设置正确,否则可能会导致日期和时间判断不准确。
      2. ctime 字段类型ctime 字段应为日期或时间类型,否则可能会导致比较结果不符合预期。可以换成数据集中其他用来和当前时间判断的日期字段。
      3. 性能考虑:如果本地数据库表数据量较大,建议在 ctime 字段上创建索引,以提高查询性能。
      4. 抽取数据集更新前清理,可以结合前置清理规则和增量更新设置。数据集定时更新设置为按日更新,9点半之前更新一次,9点半之后更新一次,实现不同数据获取更新的需求。

      5. 如果希望实时获取最新数据,可以在直连数据集模型结构sql中使用,勾选支持实时卡片数据+无缓存,实时实时查询的效果。
      6. 直连数据集缓存策略参考:https://docs.guandata.com/product/bi/428134461289267200


      路过

      雷人

      握手

      鲜花

      鸡蛋

      评论

      您需要登录后才可以发表言论 登录立即注册
      微信服务号
      联系我们
      电话:400-880-0750
      邮箱:hello@guandata.com
      Copyright © 2001-2025 观远社区 版权所有 All Rights Reserved. 浙 ICP 备15006424号-3
      去评论 去发文 返回顶部
      返回顶部