【问题标题】:How can I query just the month and day of a DATE column?如何只查询 DATE 列的月份和日期?
【发布时间】:2012-12-14 04:15:43
【问题描述】:

我的客户表中有一个出生日期 DATE 列,其中包含约 1300 万行。我想查询此表以查找出生于该月某月某日但任何年份的所有客户。

我可以通过将日期转换为 char 并对转换执行下标查询来做到这一点,还是应该创建一个附加的 char 列,将其更新为仅包含月份和日期,或者创建三个新的整数列来保存分别是月、日和年?

这将是一个非常常用的查询条件...

编辑:...该表有大约 1300 万行。

您能否提供一个最佳解决方案的示例?

【问题讨论】:

    标签: sql date casting informix


    【解决方案1】:

    如果经常使用,请考虑'functional index'。在 Informix 11.70 InfoCentre 搜索该术语会产生许多相关命中。

    你可以使用:

    WHERE MONTH(date_col) = 12 AND DAY(date_col) = 25;
    

    您还可以玩以下游戏:

    WHERE MONTH(date_col) * 100 + DAY(date_col) = 1225;
    

    这可能更适合功能索引,但对于日常使用来说不是那么清晰。您也可以轻松编写存储过程:

    请注意,在没有函数索引的情况下,对条件中的列调用函数意味着不太可能使用索引。

    CREATE FUNCTION mmdd(date_val DATE DEFAULT TODAY) RETURNING SMALLINT AS mmdd;
        RETURN MONTH(date_val) * 100 + DAY(date_val);
    END FUNCTION;
    

    并将其用作:

    WHERE mmdd(date_col) = 1225;
    

    【讨论】:

    • 最好使用索引,因为大约有 1300 万行。我想知道查询 MONTH(birthdate) 和 DAY(birthdate) 的成本是多少,而不是添加 3 个单独的整数列并用月、日和年填充它们,同时保留原始日期列。出生日期是一个很少更改的值,除非出现数据输入错误。
    • 这将取决于您实际运行的查询。如果您要确保下注者至少 21 岁,则需要完整的日期。如果您正在查看生日,那么日期和月份组件是有意义的。我不确定您希望多久(如果有的话)年和月或(更不可信)年和月的日期。所以我怀疑一年专栏是否值得。如果您进行大量生日搜索,那么月份和日期可能有意义,但我仍会进行测量,并且在单独存储之前查看功能索引。
    • 拥有 1300 万行,您将在索引中每月/每天有很多重复(一年中每天 35,000 个条目)。就其本身而言,它具有中等选择性(0.3% 的选择性还不错)。如果结合其他条件,那么它们很可能会提供替代索引。这实际上取决于您将执行的查询。
    • 嗯,查询是要确定一周前,大约 1300 万客户中的哪一个生日快到了,所以我们可以给他们送 100 美元的礼物! :-) 如果每年只有 365 或 366 个生日,您是如何得出每年 35,000 个生日的?约 1300 万客户的生日分配不均。
    • 我从 13,000,000 / 365 到一年中每天 35,000 个条目。
    【解决方案2】:

    根据您执行此操作的频率以及运行所需的速度,您可能会考虑将日期列拆分为日、月和年列。这会使搜索速度更快,但当您想要检索整个日期时会导致各种其他问题(以及验证它是否是日期的问题) - 这不是一个好主意。

    假设速度不是问题,我会这样做:

    select *
    FROM Table
    WHERE Month(*DateOfBirthColumn*) = *SomeMonth* AND DAY(*DateOfBirthColumn*) = *SomeDay*
    

    目前我面前没有informix,但我认为语法是正确的。

    【讨论】:

    • 我从一个文本文件中填充了客户表,其中日期为 char 格式,并以破折号作为分隔符,例如:12-13-2012。生日是静态的,所以将这个日期加载到一个日期列中是否有用?分别加上三个独立的整数列,分别代表月、日和年?
    • 这取决于您真正要查找生日而不是出生日期的频率。如果要足够频繁地查找生日以保证它,则考虑将 DoB 的日期和月份组件存储为一列或两列(如果有两列,则联合索引)。一个技巧是注意“闰年婴儿”的生日是在非闰年。
    • 作为一个普遍接受的传统,如果年份不是闰年,闰年婴儿会在生日前一天或生日后一天庆祝他们的生日。我等周末来庆祝我的!飞跃婴儿不会成为问题,因为查询主要是按月和按天进行的。无论如何,他们的生日必须是有效日期,例如:02-29-2012 才能将其输入到日期列中。如果日期无效,HPL 或 dbload 会拒绝它,我会通过查看加载日志文件知道。所以我可以查询所有闰年婴儿的表格:-)
    • @Jonathan,对于闰宝宝的生日:table.LeapBaby CHAR(1), SELECT * FROM table WHERE LeapBaby = "Y"
    猜你喜欢
    • 2016-11-20
    • 1970-01-01
    • 2019-06-04
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 2016-05-16
    • 1970-01-01
    • 2011-10-11
    相关资源
    最近更新 更多