随、风 2024-04-19 15:57 采纳率: 28.6%
浏览 5

SQL server数据库算法-进阶

表A

DateFormweekondays
2024-12-2312/231
2024-12-2412/242
2024-12-2512/253
2024-12-2612/264
2024-12-2712/275
2024-12-2812/286
2024-12-2912/297
2024-12-3012/301
2024-12-3112/312
2025-01-0101/013
2025-01-0201/024
2025-01-0301/035
2025-01-0401/046
2025-01-0501/057

表B

DateFormweekondays
2024-12-2312/231
2024-12-2412/232
2024-12-2512/233
2024-12-2612/234
2024-12-2712/235
2024-12-2812/236
2024-12-2912/237
2024-12-3012/301
2024-12-3112/302
2025-01-0112/303
2025-01-0212/304
2025-01-0312/305
2025-01-0412/306
2025-01-0512/307

SQL server中,如何把表A变成表B的结果?

  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-19 15:57
    关注

    引自免费微信小程序:皆我百晓生

    为了将表A转换为表B的结果,你需要根据Formweek列中的值进行分组,并在每个组内重新设置ondays列的值。由于Formweek的格式是月/日,我们可以将其转换为日期类型,然后通过计算与当前日期之间的差距得到新的一周的第一天。接下来,我们将这一周的第一天作为基准,对每个日期计算它在一周内的位置(即ondays列的值)。

    以下是详细的SQL查询步骤:

    1. 首先,我们需要创建一个辅助函数,用于将'Formweek'字符串转换为日期。在这个例子中,我们将假设'Formweek'总是表示月份的最后一周的星期一。例如,'12/23'表示12月的第23天,这通常是12月最后一周的星期一。
    CREATE FUNCTION dbo.FormweekToDateTime (@formweek NVARCHAR(5))
    RETURNS DATETIME
    AS
    BEGIN
        DECLARE @year INT, @month INT, @day INT;
    
        SET @year = SUBSTRING(@formweek, 1, 4);
        SET @month = SUBSTRING(@formweek, 6, 2);
        SET @day = CAST(SUBSTRING(@formweek, 3, 2) AS INT);
    
        RETURN DATEFROMPART(year=@year, month=@month, day=@day);
    END;
    
    1. 然后,我们使用这个函数来更新ondays列。首先,我们需要找到每个Formweek对应的起始日期(即那一周的星期一),然后计算每个日期与起始日期之间的差值,最后除以7并向上取整得到新的一周的天数。
    UPDATE A
    SET A.ondays = DATEDIFF(DAY, dbo.FormweekToDateTime(Formweek), Date) / 7 + 1
    FROM TableA A;
    
    1. 最后,我们删除不需要的行,只保留那些FormweekDate所在的月份不同的行。这里我们使用窗口函数ROW_NUMBER()来实现:
    WITH CTE AS (
        SELECT *, 
               ROW_NUMBER() OVER (PARTITION BY Formweek ORDER BY Date) AS rn
        FROM TableA
    )
    DELETE FROM CTE WHERE rn > 1;
    

    这样,表A就被转换成了类似表B的结果。请注意,这个过程依赖于Formweek总是表示当月最后一周的星期一的假设。如果你的数据不满足这个条件,可能需要调整转换逻辑。

    以下是完整的SQL脚本:

    CREATE FUNCTION dbo.FormweekToDateTime (@formweek NVARCHAR(5))
    RETURNS DATETIME
    AS
    BEGIN
        DECLARE @year INT, @month INT, @day INT;
    
        SET @year = SUBSTRING(@formweek, 1, 4);
        SET @month = SUBSTRING(@formweek, 6, 2);
        SET @day = CAST(SUBSTRING(@formweek, 3, 2) AS INT);
    
        RETURN DATEFROMPART(year=@year, month=@month, day=@day);
    END;
    
    UPDATE A
    SET A.ondays = DATEDIFF(DAY, dbo.FormweekToDateTime(Formweek), Date) / 7 + 1
    FROM TableA A;
    
    WITH CTE AS (
        SELECT *, 
               ROW_NUMBER() OVER (PARTITION BY Formweek ORDER BY Date) AS rn
        FROM TableA
    )
    DELETE FROM CTE WHERE rn > 1;
    

    执行这段代码后,表A应该会变为类似于表B的结果。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 4月19日

悬赏问题

  • ¥20 limma多组间分析最终p值只有一个
  • ¥15 nopCommerce开发问题
  • ¥15 torch.multiprocessing.spawn.ProcessExitedException: process 1 terminated with signal SIGKILL
  • ¥15 QuartusⅡ15.0编译项目后,output_files中的.jdi、.sld、.sof不更新怎么解决
  • ¥15 pycharm输出和导师的一样,但是标红
  • ¥15 想问问富文本拿到的html怎么转成docx的
  • ¥15 我看了您的文章,遇到了个问题。
  • ¥15 GitHubssh虚拟机连接不上
  • ¥15 装完kali之后下载Google输入法 重启电脑后出现以下状况 且退不出去 桌面消失 反复重启没用
  • ¥15 ESP-IDP-BLE配网连接wifi