Access SQL Update One Table In Join Based on Value in Same Table

前端 未结 1 1084
有刺的猬
有刺的猬 2021-01-24 19:09

I have a table in Access called \"tempSpring_ASN\", with the following fields (among others):

SHP_CUSTOM_5 (AutoNumber)

RECORD_TYPE (Text)

PO_NUM (Text).

相关标签:
1条回答
  • 2021-01-24 19:56

    I have also posted this answer within your new question.

    Hi AYS,

    In Access, an Update query needs to be run on a table. As a UNION query is a combination of multiple sets of records, the result set is no longer a table, and cannot be the object of an Update query as the records in the result set are no longer uniquely identified with any one particular table (even if they theoretically could be). Access is hard-coded to treat every UNION query as read-only, which makes sense when there are multiple underlying tables. There are a number of other conditions (such as a sub-query in the SELECT statement) that also trigger this condition.

    Think if it this way: if you were not using TOP 1 and your UNION query returned multiple results, how would JET know which result to apply to the unique record in your table? As such, JET treats all such cases the same.

    Unfortunately, this is the case even when all of the data is being derived from the same table. In this case, it is likely that the JET optimizer is simply not smart enough to realize that this is the case and re-phrase the query in a manner that does not use UNION.

    In this case, you can still get what you want by re-stating your query in such a way that everything references your base table. For example, you can use the following as a SELECT query to get the PO_NUM value of the previous SHP_CUSTOM_5 record:

    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
    ;
    

    You can then phrase this as an Update query as follows in order to perform the "LIN" updates:

    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)
    )
    ;
    

    This code was successful in the tests I ran with dummy data.

    Regarding your "HDR" updates, your are really performing two separate updates. 1) If the PO_NUM matches the previous record's PO_NUM, set RECORD_TYPE to "LIN" 2) If it is the first record, set RECORD_TYPE to "HDR"

    It is not clear to me why there would be a benefit to performing these actions within one query. I would recommend performing the HDR update using the "TOP 1" by SHP_CUSTOM_5 method you used in your original SELECT query example, as this will be a relatively simple UPDATE query. It is possible to use IIF() within an Update query, but I do not know what additional benefit you would gain from the additional time and complexity that would be required (it would most likely only be much less readable).

    Best of luck!

    0 讨论(0)
提交回复
热议问题