Mysql按时间进行表分区
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql按时间进行表分区相关的知识,希望对你有一定的参考价值。
参考技术A 以下是创建一张测试表TEST并且按照时间CREATE_TIME创建RANGE分区,并使用ID创建hash分区,组成复合分区。CREATE TABLE TEST (
CREATE_TIME DATETIME DEFAULT NULL, ID BIGINT(15) DEFAULT NULL
) ENGINE=INNODB DEFAULT CHARSET=utf8
PARTITION BY RANGE(TO_DAYS(CREATE_TIME)) PARTITIONS 7 SUBPARTITION BY HASH(ID) SUBPARTITIONS 16
(PARTITION P1710 VALUES LESS THAN (TO_DAYS ('2017-10-01'))
(SUBPARTITION P1710sp0 ,SUBPARTITION P1710sp1 ,
SUBPARTITION P1710sp2 ,SUBPARTITION P1710sp3 ,
SUBPARTITION P1710sp4 ,SUBPARTITION P1710sp5 ,
SUBPARTITION P1710sp6 ,SUBPARTITION P1710sp7 ,
SUBPARTITION P1710sp8 ,SUBPARTITION P1710sp9 ,
SUBPARTITION P1710sp10 ,SUBPARTITION P1710sp11 ,
SUBPARTITION P1710sp12 ,SUBPARTITION P1710sp13 ,
SUBPARTITION P1710sp14 ,SUBPARTITION P1710sp15 ),
PARTITION P1711 VALUES LESS THAN (TO_DAYS ('2017-11-01'))
(SUBPARTITION P1711sp0 ,SUBPARTITION P1711sp1 ,
SUBPARTITION P1711sp2 , SUBPARTITION P1711sp3 ,
SUBPARTITION P1711sp4 , SUBPARTITION P1711sp5 ,
SUBPARTITION P1711sp6 , SUBPARTITION P1711sp7 ,
SUBPARTITION P1711sp8 , SUBPARTITION P1711sp9 ,
SUBPARTITION P1711sp10 , SUBPARTITION P1711sp11 ,
SUBPARTITION P1711sp12 , SUBPARTITION P1711sp13 ,
SUBPARTITION P1711sp14 , SUBPARTITION P1711sp15 ),
按任意开始和结束日期对订单表进行分区
【中文标题】按任意开始和结束日期对订单表进行分区【英文标题】:Partition Orders table by arbitrary start and end day-of-month 【发布时间】:2020-08-12 05:25:14 【问题描述】:鉴于以下相当标准的订单表:
CREATE TABLE [dbo].[orders](
[bill_product_id] [int] IDENTITY(1,1) NOT NULL,
[Bill_date] [datetime] NULL,
[TenantId] [int] NULL,
[Product_type] [int] NULL,
[Quantity] [int] NULL,
[Customer_cost] [numeric](18, 10)
)
以下查询为我提供表orders
中有记录的每个月的开始日期和结束日期
SELECT distinct DATEADD(DAY,1,EOMONTH(bill_date,-1)) as start_date,
EOMONTH(bill_date) as end_date
FROM orders
示例结果集:
开始日期结束日期
2020-07-01 2020-07-31
2020-08-01 2020-08-31
现在我们需要更改“结算周期”,因此我们需要从每月 26 日开始结算周期,而不是从每月 1 日开始,到每月最后一天结束,月底是下个月的第 25 天(不要问)。
我确定我可以根据开始日期确定 end_date,但我不确定将数据划分为月份的 26 日至 25 日的最佳方式。请提出一个有效的方法来做到这一点。
【问题讨论】:
【参考方案1】:也许你可以使用DATEFROMPARTS
DECLARE @bill_date DATE = '2020-08-12'
SELECT DATEFROMPARTS(YEAR(@bill_date), MONTH(@bill_date), 26)
,DATEFROMPARTS(YEAR(@bill_date), MONTH(@bill_date) + 1, 25)
但你的方式也是有效的,可以加强。
正如你所指出的,它应该是:
SELECT DATEFROMPARTS(YEAR(@bill_date), MONTH(@bill_date) - (CASE WHEN DAY(@bill_date) >= 26 then 0 else 1 end) , 26);
为了确保小于26
的日期保持在当前间隔内,而不是像我原来的解决方案中那样的下一个。
【讨论】:
这给出了从 8 月 26 日开始的 next 间隔。我尝试从两个“月份”部分中减去 1,但如果给出的日期是“2020-”,这将不起作用07-30' - 计算到 6 月 26 日,应该是 7 月 26 日 对于2020-07-30
,我得到2020-07-26
和2020-08-25
。这不是你需要的吗?
是的,但如果给定 '2020-08-12',相同的函数会返回未来的日期 - 而不是当前的时间间隔。但是 DATEFROMPARTS 帮我找到了真正的解决方案: SELECT DATEFROMPARTS(YEAR(@bill_date), MONTH(@bill_date) - (CASE WHEN DAY(@bill_date) >= 26 then 0 else 1 end) , 26);
@Black 我现在明白逻辑了 :-)【参考方案2】:
感谢@gotqn,我可以按如下方式使用 DATEFROMPARTS
SELECT DATEFROMPARTS(YEAR(@bill_date),
MONTH(@bill_date) - (CASE WHEN DAY(@bill_date) >= 26 then 0 else 1 end),
26) as start_date
,DATEFROMPARTS(YEAR(@bill_date),
MONTH(@bill_date) + (CASE WHEN DAY(@bill_date) >= 26 then 1 else 0 end),
25) as end_date
【讨论】:
【参考方案3】:您可以减去 26 天并使用 datefromparts()
:
SELECT DISTINCT DATEFROMPARTS(YEAR(yyyymm_start), MONTH(yyyymm_start), 26) as start_date,
DATEFROMPARTS(YEAR(yyyymm_end), MONTH(yyymm_end), 25) as end_date
FROM orders o CROSS APPLY
(VALUES (DATEADD(DAY, -26, BILL_DATE),
DATEADD(MONTH, 1, DATEADD(DAY, -26, BILL_DATE))
)
) as v(yyyymm_start, yyyymm_end)
【讨论】:
【参考方案4】:只需使用 dateadd 即可“移动”您的计费周期。
我假设然后你查询
declare @billDate date = '2020-07-16'
SELECT distinct DATEADD(DAY,1,EOMONTH(@billDate)) as start_date,
EOMONTH(@billDate) as end_date, 'Original' as query
--FROM orders
SELECT distinct DATEADD(DAY,26,EOMONTH(@billDate,-1)) as start_date,
dateadd(day,25,EOMONTH(@billDate) )as end_date, 'Modified' as query
--FROM orders
会导致
start_date end_date query
---------- ---------- --------
2020-07-01 2020-07-31 Original
start_date end_date query
---------- ---------- --------
2020-07-26 2020-08-25 Modified
【讨论】:
这与@gotqn 的原始答案有相同的问题,即对于 '2020-08-10' 它返回 future 间隔 2020-08-26 到 2020-09- 25 已修复,在 eomonth 函数中添加了 -1 没有。现在它返回值“2020-07-30”的错误(先前)间隔 请张贴给定账单日期的预计开始/结束日期 这一切都在原始帖子中,也在@gotqn 的答案中。不用担心,它已经被正确回答了以上是关于Mysql按时间进行表分区的主要内容,如果未能解决你的问题,请参考以下文章