【问题标题】:MS SQL Insert most recent three dates from one table into another table matching on one columnMS SQL 将一个表中最近的三个日期插入到另一个表中匹配一列
【发布时间】:2014-03-12 15:02:27
【问题描述】:

我有一个“源”表,其中包含用户登录列表以及登录日期和时间。 “源”表如下所示...

CREATE TABLE [dbo].[tblSrc](
[userID] [varchar](50) NULL,
[date] [datetime] NULL)

出于说明目的,某些行可能包含...

userID    date
------    ----
1         2013-01-01 00:00:00.000
2         2013-01-01 00:00:00.000
3         2013-01-01 00:00:00.000
2         2013-01-02 00:00:00.000
3         2013-01-03 00:00:00.000
3         2013-01-04 00:00:00.000
1         2013-01-02 00:00:00.000
3         2013-01-05 00:00:00.000

我有一个如下的“目的地”表...

CREATE TABLE [dbo].[tblDest](
[userID] [varchar](50) NOT NULL,
[date1] [datetime] NULL,
[date2] [datetime] NULL,
[date3] [datetime] NULL)

源表中的用户 ID 包含多个重复的用户 ID,而我已使用唯一用户 ID 填充目标表。

我需要做的是遍历源表并插入每个用户的最后三个登录日期?

因此,例如,目标表会使用 userID '3'

用户 '3' 在源表中有 4 个条目

userID    date1                     date2                     date3
------    -----                     -----                     -----
3         2013-01-05 00:00:00.000   2013-01-04 00:00:00.000   2013-01-03 00:00:00.000

date1 是最近的登录日期,date2 是下一个,date3 是下一个。

我可以从每个用户 ID 的源表中获取最新日期,但我不知道如何获取三个最近的日期(假设有三个日期)并将它们插入到目标表中。

非常感谢任何帮助。

【问题讨论】:

    标签: sql


    【解决方案1】:

    这个 SQL 应该可以工作:

     with userrows as
    (SELECT t.userID, t.date,
    ROW_NUMBER() OVER(PARTITION BY t.userID ORDER BY t.date DESC) AS Row
    FROM tblSrc t)
    insert into tblDest
    select distinct
        u.userID,
    (select top 1 date from userrows u1 where u1.userID=u.userID and u1.Row=1 ) 'date1',
    (select top 1 date from userrows u2 where u2.userID=u.userID and u2.Row=2)  'date2',
    (select top 1 date from userrows u3 where u3.userID=u.userID  and u3.Row=3)  'date3'
    from userrows u
    

    要添加状态,您可以执行以下操作:

     with userrows as
    (SELECT t.userID, t.date,t.status,
    ROW_NUMBER() OVER(PARTITION BY t.userID ORDER BY t.date DESC) AS Row
    FROM tblSrc t)
    insert into tblDest
     select distinct
    u.userID,
    (select date from userrows u1 where u1.userID=u.userID and u1.Row=1 ) 'date1',
    (select status from userrows u1 where u1.userID=u.userID and u1.Row=1 ) 'status1',
    (select date from userrows u2 where u2.userID=u.userID and u2.Row=2)  'date2',
    (select status from userrows u2 where u2.userID=u.userID and u2.Row=2 ) 'status2',
    (select date from userrows u3 where u3.userID=u.userID  and u3.Row=3)  'date3',
    (select status from userrows u3 where u3.userID=u.userID and u3.Row=3 ) 'status3'
     from userrows u
    

    【讨论】:

    • 您好丹尼尔,感谢您的回复。使用上面我得到以下。 “列名或提供的值的数量与表定义不匹配。”源表和目标表中还有一些额外的列,我不确定它们是否重要。列名虽然是正确的。
    • 你好丹尼尔。我创建了一个新的“目标”表,其中只有 userID、date1、date2 和 date3 列,并且正在执行查询。所以请原谅我没有意识到额外的目标列很重要。有没有其他方法可以解决这个问题,或者我必须在结果完成时复制结果(查询仍在运行,因为有大约 2.6 亿条记录)所以我假设此时它会起作用。
    • 从上一条评论更新。跑了一夜还没完成!取消了查询并创建了一个包含 40K 记录的小得多的数据集。那是在一分钟内完成的,而且效果很好。我看到但不明白的问题是 date1 和 date 2 始终是相同的值。 Date3 确实有所不同。关于为什么会发生这种情况的任何想法?
    • 我确实有另一个查询要添加到原始查询中。如果每个条目都有关联的状态码,如“成功”或“失败”,如何修改上述 SQL 以适应每个日期条目的状态。目标表将具有三个额外的列,称为 status1、status2 和 status3,因此 date1 条目将适当地更新 status1 条目。
    • 如果我知道这是这么多数据,我可能会建议一个不同的解决方案 :-),但你也许可以一次获取一部分数据(就像你对 40K 行所做的那样)...我编辑了我的答案以显示如何以相同的样式添加状态。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-27
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 2012-09-19
    • 2015-12-27
    相关资源
    最近更新 更多