【问题标题】:SQL Query With Nearest Date for BackFilling用于回填的最近日期的 SQL 查询
【发布时间】:2017-07-27 12:42:39
【问题描述】:

我有两张桌子。

Comments
  - CommentId
  - Comment
  - CreateDate
  - SomeCompositeKey

Exceptions
  - ExceptionId
  - Color
  - CreateDate
  - SomeCompositeKey
  - ...and so on...

我的评论表正在添加一个新的Color 列,默认值为“白色”。

我需要回填并更新Comments 表上的新颜色字段。我需要根据评论的最近的CreateDate 和匹配的Exception(根据SomeCompositeKey 匹配)将Comments.Color 列设置为等于Exception.Color

这是使用 SQL Server Management Studio。

【问题讨论】:

  • 有多少种不同的颜色?如果没有那么多,您可以在 createdate 字段上使用带有 case 语句的更新。

标签: sql-server tsql ssms


【解决方案1】:

这应该可以解决问题...

IF OBJECT_ID('tempdb..#Comments', 'U') IS NULL 
BEGIN   -- DROP TABLE #Comments;
    CREATE TABLE #Comments (
        CommentId INT NOT NULL PRIMARY KEY CLUSTERED,
        Comment VARCHAR(100) NOT NULL,
        CreatedDate DATETIME NOT NULL,
        Color VARCHAR(10) NOT NULL DEFAULT('White')
        );

    INSERT #Comments (CommentId, Comment, CreatedDate)
    SELECT 
        t.n,
        'Blah Blah Blah',
        DATEADD(hh, t.n, GETDATE())
    FROM
        dbo.tfn_Tally(1500, 1) t;
END;

IF OBJECT_ID('tempdb..#Exceptions', 'U') IS NULL 
BEGIN   -- DROP TABLE #Exceptions;
    CREATE TABLE #Exceptions (
        ExceptionId INT NOT NULL PRIMARY KEY CLUSTERED,
        Color VARCHAR(10) NOT NULL,
        CreatedDate DATETIME NOT NULL
        );

    INSERT #Exceptions (ExceptionId, Color, CreatedDate)
    SELECT 
        t.n,
        CASE t.n % 9
            WHEN 0 THEN 'Red'
            WHEN 1 THEN 'Blue'
            WHEN 2 THEN 'Green'
            WHEN 3 THEN 'Yellow'
            WHEN 4 THEN 'Purple'
            WHEN 5 THEN 'Orance'
            WHEN 6 THEN 'Gray'
            WHEN 7 THEN 'White'
            WHEN 8 THEN 'Black'
        END,
        DATEADD(hh, t.n * 13, GETDATE())
    FROM
        dbo.tfn_Tally(100, 1) t;

    -- Add a unique nci on the CreatedDate column to improve performance.
    CREATE UNIQUE NONCLUSTERED INDEX uix_Exceptions_CreatedDate ON #Exceptions 
        (CreatedDate) INCLUDE (Color);
END;

--=========================================================
-- option 1 (faster when there is an index on e.CreatedDate)
UPDATE c SET
    c.Color = ex.Color
FROM
    #Comments c
    CROSS APPLY (
                SELECT TOP 1
                    e.Color
                FROM
                    #Exceptions e
                WHERE 
                    c.CreatedDate >= e.CreatedDate
                ORDER BY 
                    e.CreatedDate DESC
                ) ex;

--=========================================================
-- option 2 (faster when there is not index on e.CreatedDate)
WITH 
    cte_ExceptionRange AS (
        SELECT 
            e.Color, 
            BegData = e.CreatedDate,
            EndDate = LEAD(e.CreatedDate, 1, '9999-12-31') OVER (ORDER BY e.CreatedDate)
        FROM
            #Exceptions e
        )
UPDATE c SET
    c.Color = er.Color
FROM
    #Comments c
    JOIN cte_ExceptionRange er
        ON c.CreatedDate >= er.BegData
        AND c.CreatedDate <er.EndDate;

HTH,杰森

【讨论】:

    【解决方案2】:

    检查这个查询,它可能会帮助你实现你所需要的

    ;with data 
    as
    (
      Select ExceptionId,Color, SomeCompositeKey
      ,row_number() over  (partition by SomeCompositeKey order by CreateDate desc) rowNumber 
      from   Exceptions
    )
      update Comments set newColor=d.Color 
      from data d where d.rowNumber=1 
      and Comments.SomeCompositeKey=d.SomeCompositeKey
    

    【讨论】:

      猜你喜欢
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 2012-09-07
      • 1970-01-01
      • 2016-03-04
      • 1970-01-01
      • 2021-10-09
      • 1970-01-01
      相关资源
      最近更新 更多