【问题标题】:SQL Query - Copy Values in Same TableSQL 查询 - 复制同一表中的值
【发布时间】:2009-09-09 14:55:41
【问题描述】:

所以我有一个看起来像这样的表:

项目 ID 任务 ID 日期 000 001 2009 年 10 月 28 日 000 002 09 年 12 月 1 日 000 003 02/24/10 001 001 04/14/10 001 002 07/5/10 001 003 2011 年 2 月 24 日 002 001 06/07/10 002 002 07/7/10 002 003 2012 年 9 月 13 日

假设有许多项目和许多任务,但每个项目都包含相同的任务。我想按以下方式复制日期:

一个项目 (000) 具有主日期。我想将每个任务的这些日期复制到其他几个项目(示例数据中的 001、002)。

因此,如果项目 000 中的任务 001 的日期为 10/28/09,我希望其他项目中的任务 001(我知道他们的 ID)具有相同的日期。

如果项目 001 中的任务 002 的日期为 12/1/09,我希望任务 002 在其他每个项目中也有此日期。

有没有一个查询可以做到这一点?我认为应该有,但我现在想不通。

顺便说一句,我使用的是 SqlServer 2005。

【问题讨论】:

    标签: sql sql-server sql-server-2005


    【解决方案1】:
    UPDATE dbo.Projects
    SET Date = (SELECT Date FROM dbo.Projects p1
                WHERE p1.ProjectID = '000' AND p1.TaskID = dbo.Projects.TaskID)
    WHERE ProjectID IN ('P01', 'P02', 'P03', 'P04')
    AND TaskID IN ('001', '002', '003')
    

    这对你有用吗?

    所以对于TaskID = 001,这条语句会

     SELECT Date FROM dbo.Projects WHERE ProjectID = '000' AND TaskID = '001'
    

    然后将每个项目 (P01-P04) 和 TaskID=001 更新到此日期。这就是你要找的东西,不是吗?

    您还可以使用 OUTPUT 子句向您证明正在更新的内容:

    UPDATE dbo.Projects
    SET Date = (SELECT Date FROM dbo.Projects p1
                WHERE p1.ProjectID = '000' AND p1.TaskID = dbo.Projects.TaskID)
    OUTPUT inserted.ProjectID, inserted.TaskID, inserted.Date
    WHERE ProjectID IN ('P01', 'P02', 'P03', 'P04')
    AND TaskID IN ('001', '002', '003')
    

    这将导致更新每一行以输出新值(例如更新后),因此您可以检查并查看更新的内容以及更新的值。

    刚刚运行查询,这是我得到的结果:

    ProjectID   TaskID  Date
       0       1    2009-10-28 00:00:00.000
       0       2    2009-12-01 00:00:00.000
       0       3    2010-02-24 00:00:00.000
       1       1    2009-10-28 00:00:00.000
       1       2    2009-12-01 00:00:00.000
       1       3    2010-02-24 00:00:00.000
       2       1    2009-10-28 00:00:00.000
       2       2    2009-12-01 00:00:00.000
       2       3    2010-02-24 00:00:00.000
    

    项目 1 和 2 以及任务 1、2、3 的日期已设置为“主”项目 0 的值。

    【讨论】:

    • 乍一看,这个查询似乎并不匹配每个任务的从主人到其他人的日期。我读错了吗?
    • 它为您正在处理的每个 TaskID 从项目“000”中选择“日期”,并将其他项目的“日期”设置为该选定日期
    • 投票给你的人是在抽烟,这很有效并且有很好的解释。非常感谢!
    • 您被否决了,因为在 SET 列表中执行额外的 SELECT 会导致不必要的标量计算和执行计划中的顶级步骤,而使用 JOIN 不会。
    • @CptSkippy:感谢您解释您的动机。好的,同意 - 这不是绝对必要的,可以通过其他方式完成。然而,在这个规模上——三个项目和三个任务——我怀疑它是否真的会产生可衡量的差异.....
    【解决方案2】:

    大概是这样的:

    INSERT INTO Projects(ProjectID, TaskID, Date)
    SELECT P2.ProjectId, P1.TaskID, P1.Date
    FROM Projects P1
    CROSS JOIN (SELECT DISTINCT ProjectID FROM Projects WHERE ProjectId <> '000') P2
    

    我不确定您使用的是哪个数据库引擎,有些可能允许比上述更自然的语法。

    以上显然还假设尚未为其他项目设置时间段,并且您正在尝试定义新的时间段而不是更新现有的时间段。

    【讨论】:

      【解决方案3】:

      这应该可以正常工作:

      UPDATE projects SET [date] = (SELECT [date] FROM projects p1 WHERE project = '000' AND p1.task = projects.task)
      

      【讨论】:

        【解决方案4】:

        这是您想要的,只需将“...”替换为 CSV 项目列表即可。

        UPDATE c
        SET c.Date = p.Date
        FROM Projects AS [c]
        JOIN Projects AS [p]
            ON p.TaskID = c.TaskID
            AND p.ProjectID = '000'
        WHERE c.ProjectID IN (...)
        

        【讨论】:

          【解决方案5】:
          DECLARE @MasterProjectId varchar(10)
          DECLARE @ChildProjectIds varchar(100)
          
          Select 
          @MasterProjectId = '000',
          @ChildProjectIds = '''123'',''456'''
          
          
          EXECUTE sp_executesql N'Update childProjects
          Set childProjects.[Date]= masterProject.[Date]
          from Projects masterProject
          Inner join Projects childProjects on childProjects.TaskId = masterProject.TaskId and childProjects.ProjectId in (' + @ChildProjectIds + ')
          where masterProject.ProjectId = ' + @MasterProjectId
          

          【讨论】:

          • 真的没有必要创建动态 SQL 语句并执行它——看起来过于复杂,IMO
          • 为了更好地格式化您的代码,您应该突出显示您的代码行,然后按工具栏上的“代码”按钮 (010 101) - 让世界变得与众不同!
          猜你喜欢
          • 2021-06-06
          • 2014-12-27
          • 2020-11-14
          • 1970-01-01
          • 1970-01-01
          • 2011-05-29
          • 2017-04-23
          • 2022-10-08
          • 1970-01-01
          相关资源
          最近更新 更多