【问题标题】:increment row with multiple joined tables具有多个连接表的增量行
【发布时间】:2013-06-10 22:43:34
【问题描述】:

我正在尝试更新 tblForm10Objectives,根据从 tblForm10Goals、tblForm10GoalsObjectives 和 tblForm10Objectives 的连接返回的行数,将 ObjectiveNumber 列设置为从 1 开始的递增数字,其中 ID_Agency = tblForm10Goals 中的代理 ID,

到目前为止的示例查询:

UPDATE dbo.tblForm10Objectives
SET ObjectiveNumber = rn
FROM tblForm10Goals As g
    Left Join tblForm10GoalsObjectives gobs ON g.ID_Form10Goal = gobs.ID_Form10Goal
    Right Join 
(
    SELECT
        ROW_NUMBER() OVER (PARTITION BY g.ID_Agency
                            ORDER BY OB.ID_Form10Objective) AS rn,
        OB.ID_Form10Objective

    FROM tblForm10Goals g
    LEFT JOIN dbo.tblForm10GoalsObjectives gobs ON g.ID_Form10Goal = gobs.ID_Form10Goal
    RIGHT JOIN dbo.tblForm10Objectives OB ON gobs.ID_Form10Objective = OB.ID_Form10Objective
    Where g.ID_Agency = 2
) rns ON dbo.tblForm10Objectives.ID_Form10Object = rns.ID_Form10Objective

内部 select 语句返回正确递增的 ObjectiveNumber 值,我只需将 dbo.tblForm10Objectives 更新为 ObjectiveNumber = rn。提前感谢您的任何帮助。

脚本化表格

第一个表

 CREATE TABLE [dbo].[tblForm10Goals](
    [ID_Form10Goal] [int] IDENTITY(1,1) NOT NULL,
    [ID_Agency] [int] NOT NULL,
    [GoalNumber] [int] NULL,
    [GoalDescription] [varchar](1200) NULL,
    [Locked] [bit] NULL,
 CONSTRAINT [PK_tblForm10Goals] PRIMARY KEY CLUSTERED 
(
    [ID_Form10Goal] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

第二张表

CREATE TABLE [dbo].[tblForm10GoalsObjectives](
    [ID_Form10GoalObjective] [int] IDENTITY(1,1) NOT NULL,
    [ID_Form10Goal] [int] NOT NULL,
    [ID_Form10Objective] [int] NOT NULL,
 CONSTRAINT [PK_tblForm10GoalsObjectives] PRIMARY KEY CLUSTERED 
(
    [ID_Form10GoalObjective] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

第三张桌子

CREATE TABLE [dbo].[tblForm10Objectives](
    [ID_Form10Objective] [int] IDENTITY(1,1) NOT NULL,
    [ObjectiveNumber] [int] NULL,
    [ObjectiveDescription] [varchar](1200) NULL,
    [UnitofMeasure] [varchar](100) NULL,
    [Q1Target] [varchar](50) NULL,
    [Q1Actual] [varchar](50) NULL,
    [Q1ActualLocked] [bit] NULL,
    [Q2Target] [varchar](50) NULL,
    [Q2Actual] [varchar](50) NULL,
    [Q2ActualLocked] [bit] NULL,
    [Q3Target] [varchar](50) NULL,
    [Q3Actual] [varchar](50) NULL,
    [Q3ActualLocked] [bit] NULL,
    [Q4Target] [varchar](50) NULL,
    [Q4Actual] [varchar](50) NULL,
    [Q4ActualLocked] [bit] NULL,
    [AnnualTarget] [varchar](50) NULL,
    [AnnualActual] [varchar](50) NULL,
    [AnnualActualLocked] [bit] NULL,
    [TargetsLocked] [bit] NULL,
    [Locked] [bit] NULL,
 CONSTRAINT [PK_tblForm10Objectives] PRIMARY KEY CLUSTERED 
(
    [ID_Form10Objective] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

【问题讨论】:

  • 根据您的窗口函数的格式,看起来您正在使用 MS SQL。如果是这样,请标记您的问题,以便我们知道如何为您提供帮助。
  • @JonofAllTrades:窗口函数的“format”适用于大多数现代 DBMS。 tbl 前缀和 dbo 模式的存在暗示了 MS SQL。
  • 我把它改成了 sql-server-2008,对不起....

标签: sql-server-2008


【解决方案1】:

这是带有 JOIN 的 UPDATE 的基本格式:

UPDATE
    A
SET
    A.field = B.field
FROM table1 A
JOIN table2 B
    ON A.ID = B.ID
WHERE --Additional limiting criteria if needed.

鉴于此,并假设您的联接正常工作,我相信以下内容应该有效:

UPDATE
    OB
SET
    ObjectiveNumber =   ROW_NUMBER() OVER (PARTITION BY g.ID_Agency
                        ORDER BY OB.ID_Form10Objective)
FROM tblForm10Goals g
LEFT JOIN dbo.tblForm10GoalsObjectives gobs ON g.ID_Form10Goal = gobs.ID_Form10Goal
RIGHT JOIN dbo.tblForm10Objectives OB ON gobs.ID_Form10Objective = OB.ID_Form10Objective
Where g.ID_Agency = 2

【讨论】:

  • 当我运行您上面给出的查询时,我收到以下错误:Msg 4108, Level 15, State 1, Line 5 窗口函数只能出现在 SELECT 或 ORDER BY 子句中。
  • 所以将 Row_Number 创建脚本移动到子查询中,并且只将更新的表加入其中。
【解决方案2】:

想到三件事。

  1. tblForm10GoalsObjectives 的第一个连接似乎未使用,根据名称我猜它正在创建重复记录。如果前两个表之间的关系不是一对一的,就会破坏UPDATE
  2. RIGHT JOIN 应该是INNER JOIN。排除第一个表的半联接无法应用任何更新。
  3. 您的错误信息是什么?或者你只是没有得到你期望的结果?请详细说明。

这是一个尝试重写:

UPDATE Objs
SET ObjectiveNumber = RowNumbers.RowNumber
FROM tblForm10Objectives AS Objs
    INNER JOIN tblForm10GoalsObjectives AS GObjs ON Objs.ID_Form10Objective = GObjs.ID_Form10Objective
    INNER JOIN
        (
        SELECT
            Objs.ID_Form10Objective,
            ROW_NUMBER() OVER (PARTITION BY G.ID_Agency ORDER BY Objs.ID_Form10Objective) AS RowNumber
        FROM
            dbo.tblForm10Objectives AS Objs
            INNER JOIN dbo.tblForm10GoalsObjectives AS GObjs ON Objs.ID_Form10Objective = GObjs.ID_Form10Objective
            INNER JOIN tblForm10Goals AS G ON GObjs.ID_Form10Goal = G.ID_Form10Goal
        WHERE
            G.ID_Agency = 2
        ) AS RowNumbers ON GObjs.ID_Form10Objective = RowNumbers.ID_Form10Objective

【讨论】:

  • 报错信息为:无法绑定多部分标识符“dbo.Form10Objectives.ID_Form10Objective”。这显示在最后一行; rns ON dbo.tblForm10Objectives.ID_Form10Object = rns.ID_Form10Objective 内部选择效果很好,它使用 ObjectiveNumbers 提取正确的数据,因为我希望它们在更新语句中更新。我无法让更新与内部选择一起使用...
  • 啊,我错过了。你通过分配别名然后使用原始表名加入,而不是将更新的表放在第一位,这让我失望了。我已经起草了一个替代方案,但在不了解您的表格之间的关系的情况下,这只是在黑暗中的一个镜头。
  • 有什么方法可以直接给你发邮件吗?您的内部选择也有效。但是问题仍然在更新语句中,在调用 SET ObjectiveNumber 的地方,它表明 ObjectiveNumber 无效。在底部声明; AS RowNumbers ON GOBS.ID_Form10Objective = RowNumbers.ID_Form10Objective,GOBS.ID_Form10Objective 是无效列。我会发布表格结构,但这不会让我发布我的声誉点不等于 10 或更高的图像。
  • 我更愿意在 SO 中将其散列。请不要发布图片,更好的选择是CREATE TABLE 脚本(请减少到字段、PK 和英国,不需要SET ANSI_NULLS 样板)。另外,如果您能解释表之间的关系,那将有所帮助。
  • 我在原始帖子下发布了脚本表格。脚本表位于标题脚本表下。第一个表的主键 ID_Form10Goal。第二个表有一个主键 ID_Form10GoalObjective 和以下外键; ID_Form10 目标,ID_Form10 目标。 tblForm10Objectives 的主键为 ID_Form10Objective。
猜你喜欢
  • 2016-10-05
  • 2020-01-04
  • 2021-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-19
  • 2014-03-06
相关资源
最近更新 更多