当前位置: 首页 > 面试题库 >

根据同一表中的值访问联接中的SQL更新一个表

郑胡媚
2023-03-14
问题内容

我在Access中有一个名为“ tempSpring_ASN”的表,其中包含以下字段(以及其他字段):

SHP_CUSTOM_5(自动编号)

RECORD_TYPE(文本)

PO_NUM(文本)。

我需要更改RECORD_TYPE的值,以便如果PO_NUM与上一条记录中的PO_NUM相同,则RECORD_TYPE应该为“
LIN”,否则(或者,如果它是第一条记录),则RECORD_TYPE应该为“ HDR”。

我创建了以下查询,以获取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已更新,但Table5未更新。显然,如果一个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
        );

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


问题答案:

我还在您的新问题中发布了此答案。

嗨,AYS,

在Access中,需要在表上运行更新查询。由于UNION查询是多组记录的组合,因此结果集不再是表,并且不能成为Update查询的对象,因为结果集中的记录不再与任何一个特定的表唯一地标识(甚至(如果理论上可以)。访问经过硬编码,以将每个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
;

然后,您可以按如下所示将此短语表述为Update查询,以执行“ 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)
)
;

代码在我使用伪数据进行的测试中成功。

关于“ HDR”更新,您实际上是在执行两个单独的更新。1)如果PO_NUM与先前记录的PO_NUM相匹配,则将RECORD_TYPE设置为“ LIN”
2)如果是第一条记录,则将RECORD_TYPE设置为“ HDR”

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

祝你好运!



 类似资料:
  • 问题内容: 我在SQLite中有两个表,看起来像这样 我试图编写查询以基于表Y中的记录更新表X上的记录。更新的条件如下所示 但是当我尝试这样做时,我收到一条错误消息,说 没有这样的列:table_y.c2 问题答案: 删除的答案关于错误的原因是正确的:必须在查询中 引入 关系标识符(例如,使用FROM / JOIN),然后才能使用它。 虽然SQLite的不 不 支持(因此没有办法直接引入查找关系)

  • 问题内容: 我正在尝试用TYPE2中找到的值覆盖TYPE1中找到的值。 我编写了此SQL进行尝试,但是由于某种原因它没有更新: http://www.sqlfiddle.com/#!3/a4733/17 为什么我的TYPE1中的值没有更新? 问题答案: 这对我有用

  • 我试图用Python复制我的Stata代码,我被指向熊猫的方向。然而,我很难思考如何处理数据。 假设我想遍历列标题“ID”中的所有值。如果该ID与一个特定的数字匹配,那么我想更改两个相应的值FirstName和LastName。 在Stata,它看起来像这样: 因此,这将替换 FirstName 中与 ID == 103 到 Matt 的值对应的所有值。 在熊猫身上,我正在尝试这样的东西 不知道该

  • 创建一个Java方法,它将列表作为参数(MasterList)并返回另一个列表(ExpectedList)。 列表中每个对象都有两个变量: null 我试图实现的逻辑是:当有多个ID相同的对象时,只考虑计数较大的特定对象。表示ID:有3个对象,所以我只考虑(ID:abc122,Count:20),因为在ID:abc122的对象中Count更高。在结束时,方法应返回

  • 问题内容: 我需要根据从以下两个表中提取的数据创建一个新表: 第一表: 第二张表: 新表应包含一个“ Var”列和一个“Number”列,其中每个变量将包含一行带有cur_number的行,其余各行将包含第二个表的new_number列中的数字,其中。例如,在上面显示的示例中,对于A,将有一行,行数为10(其cur_number),另一行为“ 2”(因为2 <10,但是11>10)。 在我的示例中

  • 我正忙着创建VB. Net Windows应用程序。我正在使用带有名为skedulering的表的microsoft sql服务器数据库。我正在尝试使用基于另一列(即Kode)的唯一值更新一列(即Groep)。此值接受Kode值的前三个字符并向其添加一个整数。我认为我的意思最好用以下内容来解释: 所有红色边框行都具有相同的Groep值。有人能帮我创建sql语句吗? 问候