You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL自定义周数计算:匹配MSSQL DATENAME(week)逻辑

在PostgreSQL中实现MSSQL DATENAME(week)风格的周数计算

要实现你描述的特定周数规则(与MSSQL默认的DATENAME(week)逻辑一致),可以通过自定义函数或纯SQL表达式实现,以下是具体方案:

核心逻辑分析

你需要的规则本质是:

  • 一年的第1周包含该年1月1日,无论这一周有几天
  • 从1月1日后的第一个周一开始,每7天为一个完整周,周数依次递增
  • 2021年底的最后几天仍归属上一年的第53周,2022年初的前2天归属当年第1周

方案1:自定义PL/pgSQL函数

创建一个可复用的函数,直接返回符合规则的周数:

CREATE OR REPLACE FUNCTION get_mssql_week(d date)
RETURNS integer
LANGUAGE plpgsql
IMMUTABLE
AS $$
DECLARE
    y integer := extract(year from d)::integer;
    first_day date := make_date(y, 1, 1);
    -- 计算当年1月1日后的第一个周一
    first_monday date := first_day + (8 - extract(isodow from first_day)::integer) % 7;
BEGIN
    -- 1月1日到第一个周一前的日期都属于第1周
    IF d < first_monday THEN
        RETURN 1;
    ELSE
        -- 从第一个周一开始,每7天递增一周数
        RETURN 1 + ((d - first_monday)::integer / 7) + 1;
    END IF;
END;
$$;

方案2:纯SQL表达式

如果不想创建函数,可直接使用以下SQL表达式计算单日期的周数:

WITH date_params AS (
    SELECT
        '2021-12-27'::date AS target_date, -- 替换为你需要计算的日期
        extract(year from '2021-12-27'::date)::integer AS year_num
)
SELECT
    CASE
        WHEN target_date < make_date(year_num, 1, 1) + (8 - extract(isodow from make_date(year_num, 1, 1))::int) %7 THEN 1
        ELSE 1 + ((target_date - (make_date(year_num, 1, 1) + (8 - extract(isodow from make_date(year_num, 1, 1))::int) %7))::int /7) +1
    END AS mssql_week
FROM date_params;

测试验证

用你的测试用例验证:

-- 2021年12月27-31日 → 53周
SELECT get_mssql_week('2021-12-27'); -- 返回53
SELECT get_mssql_week('2021-12-31'); -- 返回53

-- 2022年1月1-2日 → 1周
SELECT get_mssql_week('2022-01-01'); -- 返回1
SELECT get_mssql_week('2022-01-02'); -- 返回1

-- 2022年1月3日 → 2周
SELECT get_mssql_week('2022-01-03'); -- 返回2

-- 2022年1月10日 →3周
SELECT get_mssql_week('2022-01-10'); -- 返回3

为什么PostgreSQL内置格式符不适用

  • IW:ISO周规则,每年第一周需包含至少4天,且周一为周起始,导致2021-12-27被算作2022年第1周,不符合需求
  • WW:以1月1日为当年第1周起始,每周从周日开始,每7天递增一周,导致2022-01-03仍属于第1周,与需求不符

内容的提问来源于stack exchange,提问作者Роман Иванов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 16:18:21