访问SQL更新一个表的基础上的价值在同一个表加入(Access SQL Update One Tab

2019-08-16 23:22发布

我在访问被称为“tempSpring_ASN”表,具有以下字段(其中包括):

SHP_CUSTOM_5(自动编号)

RECORD_TYPE(文本)

PO_NUM(文本)。

我需要改变RECORD_TYPE,的值,如果PO_NUM是在以前的记录一样PO_NUM,然后RECORD_TYPE应该是“LIN”,否则(或者如果它是第一个记录),RECORD_TYPE应该是“人类发展报告”。

我创建了以下查询来获取RECORD_TYPE正确的新价值:

SELECT TOP 1 t1.SHP_CUSTOM_5,
    t1.PO_NUM AS CurrentValue,
    NULL AS PreviousValue,
    "HDR" AS RECORD_TYPE
FROM tempSpring_ASN AS t1
ORDER BY t1.SHP_CUSTOM_5
UNION ALL
SELECT t1.SHP_CUSTOM_5,
    t1.PO_NUM AS CurrentValue,
    t2.PO_NUM AS PreviousValue,
    IIf([CurrentValue]=[PreviousValue],'LIN','HDR') AS RECORD_TYPE
FROM tempSpring_ASN AS t1,
    tempSpring_ASN AS t2
WHERE t1.SHP_CUSTOM_5 = t2.SHP_CUSTOM_5 + 1
ORDER BY t1.SHP_CUSTOM_5;

我保存的查询为“tempSpring_ASN_With_PreviousRow”。 现在,我想用它来更新与下面的查询原tempSpring_ASN表:

UPDATE tempSpring_ASN INNER JOIN tempSpring_ASN_With_PreviousRow ON tempSpring_ASN.SHP_CUSTOM_5 = tempSpring_ASN_With_PreviousRow.SHP_CUSTOM_5 SET tempSpring_ASN.RECORD_TYPE = [tempSpring_ASN_With_PreviousRow].[RECORD_TYPE];

但我发现,“操作必须使用一个可更新的查询。” 我不知道这是否是因为我想在一个连接来更新一个表,或者是因为我试图更新基于在同一个表,或由于别的东西值的表。 无论如何,我在寻找一些工作。

谢谢!

更新 (没有双关语意):

我试过下面的更新查询:

UPDATE tempSpring_ASN INNER JOIN Table5 ON tempSpring_ASN.SHP_CUSTOM_5 = Table5.SHP_CUSTOM_5 SET tempSpring_ASN.RECORD_TYPE = "zzz";

它工作得很好。 其结果是,tempSpring_ASN已更新,但表5-1是不是。 很明显,如果两个表在SQL语句中加入了,即使您运行在一个表上的更新,它仍然不会尝试更新中加入其他表。 既然如此,我不知道为什么我的原始更新查询将行不通。 我知道,tempSpring_ASN_With_PreviousRow不可更新,因为它是一个UNION查询,但我并不对其进行更新。 相反,我试图更新tempSpring_ASN -其他表的加盟,这可更新的。

更新2:然后我试图使用相关子查询,如下所示:

UPDATE tempSpring_ASN AS t
SET t.RECORD_TYPE = (
        SELECT RECORD_TYPE
        FROM (
            SELECT TOP 1 t1.SHP_CUSTOM_5,
                t1.PO_NUM AS CurrentValue,
                NULL AS PreviousValue,
                "HDR" AS RECORD_TYPE
            FROM tempSpring_ASN AS t1
            ORDER BY t1.SHP_CUSTOM_5
            UNION ALL
            SELECT t1.SHP_CUSTOM_5,
                t1.PO_NUM AS CurrentValue,
                t2.PO_NUM AS PreviousValue,
                IIf([CurrentValue] = [PreviousValue], 'LIN', 'HDR') AS RECORD_TYPE
            FROM tempSpring_ASN AS t1,
                tempSpring_ASN AS t2
            WHERE t1.SHP_CUSTOM_5 = t2.SHP_CUSTOM_5 + 1
            ORDER BY t1.SHP_CUSTOM_5
            )
        WHERE SHP_CUSTOM_5 = t.SHP_CUSTOM_5
        );

但我仍然收到“操作必须使用一个可更新的查询。”

更新3:

我认为错误是由于这样的事实,我使用的是联合查询。 为了找出问题,我已经试过以下(这不会给我我想要的结果,但会帮我诊断问题。):

UPDATE tempSpring_ASN AS t
SET t.RECORD_TYPE = (
        SELECT TOP 1 RECORD_TYPE
        FROM tempSpring_ASN_With_PreviousRow
        );

它给了我同样的错误。 所以,现在的问题变成,我为什么不能使用联合查询的输出的一个值来设置一个记录的值?

Answer 1:

我还贴出你的新问题中的这个答案。

嗨AYS,

在Access中,更新查询需要在一个表上运行。 如UNION查询是多组的记录的组合,则结果集不再是表,并且如在结果集中的记录不再唯一地与任何一个特定的表中标识不能更新查询的对象(甚至如果他们在理论上可以)。 访问是硬编码的对待每一个UNION查询为只读,这是有意义的,当有多个基础表。 还有一些其他条件(如SELECT语句中的一个子查询)也触发这个条件。

如果你没有使用TOP 1的UNION查询返回的多个结果,怎么会知道JET适用于你的表格中唯一的记录,其结果是:想如果这样说? 因此,JET将所有这样的情况相同。

不幸的是,即使所有的数据都从同一个表中导出的情况。 在这种情况下,很可能的是,JET优化是不够明智地意识到这种情况并重新短语不使用UNION的方式查询。

在这种情况下,你仍然可以得到你想要的东西通过重新说明你的查询以这样的方式,一切都引用基表。 例如,你可以使用下面的SELECT查询来获取先前SHP_CUSTOM_5记录的PO_NUM值:

SELECT
t1.SHP_CUSTOM_5
, t1.PO_NUM
, t1.SHP_CUSTOM_5 -1 AS PREV_RECORD

, (SELECT
t2.PO_NUM
FROM
tempSpring_ASN As t2
WHERE
t2.SHP_CUSTOM_5 = (t1.SHP_CUSTOM_5 -1)
) AS PREV_PO

FROM
tempSpring_ASN AS t1
;

然后,您可以短语以此为更新查询,如下所示,以执行“LIN”的更新:

UPDATE
tempSpring_ASN AS t1 

SET 
t1.RECORD_TYPE = "LIN"

WHERE
t1.PO_NUM=

(
SELECT 
t2.PO_NUM

FROM
tempSpring_ASN As t2

WHERE
t2.SHP_CUSTOM_5 = (t1.SHP_CUSTOM_5 -1)
)
;

此代码是成功的在我与虚拟数据运行测试。

关于你的“人类发展报告”的更新,你真的执行两个单独的更新。 1)如果PO_NUM先前记录的PO_NUM,设置RECORD_TYPE匹配“LIN” 2)如果是第一个记录,设置RECORD_TYPE为“HDR”

这是我不清楚为什么会有一个查询中执行这些操作是有利的。 我会建议执行使用“TOP 1”你在原来的SELECT查询示例中使用SHP_CUSTOM_5方法HDR更新,因为这将是一个相对简单的UPDATE查询。 它可以更新查询中使用IIF(),但我不知道你会从将被要求额外的时间和复杂性中获得什么额外的好处(这很可能会只少得多可读)。

祝您好运!



文章来源: Access SQL Update One Table In Join Based on Value in Same Table