CASE in UPDATE produces unexpected results. Fixed when moved to WHERE clause. Why?How can a LEFT OUTER JOIN return more records than exist in the left table?Why use the INCLUDE clause when creating an index?What are the options for storing hierarchical data in a relational database?why have left join at all(why not just have outer join with condition in where clause)Case When Condition in Where ClauseOuter join giving same results as inner join if using where clauseUpdate SQL when where clause condition can be nullCase statement in where clause not workingGet the value of END AS column in case when in where clauseIF Condition Perform Query, Else Perform Other Query Base on Count to Execute

Where is the USB2 OTG port on the RPi 4 Model B located?

PIC12F675 GP4 doesn't work

What are the steps/action plan to introduce Test Automation in a company?

Was I subtly told to resign?

Do native speakers use ZVE or CPU?

The monorail explodes before I can get on it

Are neural networks prone to catastrophic forgetting?

How can an advanced civilization forget how to manufacture its technology?

Is purchasing foreign currency before going abroad a losing proposition?

Why can't supermassive black holes merge? (or can they?)

How do Windows version numbers work?

Referring to different instances of the same character in time travel

Why does the autopilot disengage even when it does not receive pilot input?

Who Can Help Retag This?

I have a ruthless DM and I'm considering leaving the party. What are my options to minimize the negative impact to the rest of the group?

Why does resistance reduce when a conductive fabric is stretched?

Is Prophet from Facebook any different from a linear regression?

Does Google Maps take into account hills/inclines for route times?

How the name "craqueuhhe" is read

Why did the Japanese attack the Aleutians at the same time as Midway?

How to achieve this rough borders and stippled illustration look?

Are there any double stars that I can actually see orbit each other?

As the Dungeon Master, how do I handle a player that insists on a specific class when I already know that choice will cause issues?

Optimising Table wrapping over a Select



CASE in UPDATE produces unexpected results. Fixed when moved to WHERE clause. Why?


How can a LEFT OUTER JOIN return more records than exist in the left table?Why use the INCLUDE clause when creating an index?What are the options for storing hierarchical data in a relational database?why have left join at all(why not just have outer join with condition in where clause)Case When Condition in Where ClauseOuter join giving same results as inner join if using where clauseUpdate SQL when where clause condition can be nullCase statement in where clause not workingGet the value of END AS column in case when in where clauseIF Condition Perform Query, Else Perform Other Query Base on Count to Execute






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








3















I created a query to update a flag, I used a CASE statement to determine the value. However when I run the query as an UPDATE statement only about half of the expected rows are updated? More interestingly I have run the exact same UPDATE query previously on the same data and it worked as expected (looking at the old vs new is what caused me to investigate).



I tried SELECT query using the same CASE statement, I get the correct results, but switching it back to UPDATE only updates roughly half the records.



Moving the criteria to the WHERE clause fixed the issue. It seems to be the CASE statement in the SET part that causes problems. I can't figure out why? I'd like to know so that avoid whatever mistake I've made in the future.



Original Code:



UPDATE D
SET PUBLISH_FLAG =
CASE WHEN
MAPPED_CAT NOT IN(1,2,3)
AND SRC != '999'
AND RECEIVED_DATE is not null
AND RECEIVED_DATE <= D.CENSUS_DATE
AND SCHEDULED_FLAG = 'N'
THEN 'Y'
ELSE 'N'
END
FROM TBL_DATA D
INNER JOIN TBL_PUBLISH V
ON D.ID = V.ID
AND D.CENSUS_DATE = V.CENSUS_DATE
AND D.VERSION_NUMBER = V.VERSION_NUMBER
LEFT JOIN TBL_CAT_MAP C
ON D.SRC_CATEGORY = C.SOURCE_CAT


Working code:



UPDATE D
SET PUBLISH_FLAG = 'Y'
FROM TBL_DATA D
INNER JOIN TBL_PUBLISH V
ON D.ID = V.ID
AND D.CENSUS_DATE = V.CENSUS_DATE
AND D.VERSION_NUMBER = V.VERSION_NUMBER
LEFT JOIN TBL_CAT_MAP C
ON D.SRC_CATEGORY = C.SOURCE_CAT
WHERE
MAPPED_CAT NOT IN(1,2,3)
AND SRC != '999'
AND RECEIVED_DATE is not null
AND RECEIVED_DATE <= D.CENSUS_DATE
AND SCHEDULED_FLAG = 'N'



I thought that both should produce exactly the same results? What am I missing?



To help clarify the below code has 2 shows the difference, the 'PUBLISH_FLAG' column (updated using either my original code or PSK's answer) has 10162 'Y' values (the rest 'N'), the pub_2 column has the correct 18917 'Y' values.



SELECT
PUBLISH_FLAG,
CASE WHEN
MAPPED_CAT NOT IN(1,2,3)
AND SRC != '999'
AND RECEIVED_DATE is not null
AND RECEIVED_DATE <= D.CENSUS_DATE
AND SCHEDULED_FLAG = 'N'
THEN 'Y'
ELSE 'N'
END as pub_2
FROM TBL_DATA D
INNER JOIN TBL_PUBLISH V
ON D.ID = V.ID
AND D.CENSUS_DATE = V.CENSUS_DATE
AND D.VERSION_NUMBER = V.VERSION_NUMBER
LEFT JOIN TBL_CAT_MAP C
ON D.SRC_CATEGORY = C.SOURCE_CAT
WHERE
CASE WHEN
MAPPED_CAT NOT IN(1,2,3)
AND SRC != '999'
AND RECEIVED_DATE is not null
AND RECEIVED_DATE <= D.CENSUS_DATE
AND SCHEDULED_FLAG = 'N'
THEN 'Y'
ELSE 'N'
END = 'Y'









share|improve this question






























    3















    I created a query to update a flag, I used a CASE statement to determine the value. However when I run the query as an UPDATE statement only about half of the expected rows are updated? More interestingly I have run the exact same UPDATE query previously on the same data and it worked as expected (looking at the old vs new is what caused me to investigate).



    I tried SELECT query using the same CASE statement, I get the correct results, but switching it back to UPDATE only updates roughly half the records.



    Moving the criteria to the WHERE clause fixed the issue. It seems to be the CASE statement in the SET part that causes problems. I can't figure out why? I'd like to know so that avoid whatever mistake I've made in the future.



    Original Code:



    UPDATE D
    SET PUBLISH_FLAG =
    CASE WHEN
    MAPPED_CAT NOT IN(1,2,3)
    AND SRC != '999'
    AND RECEIVED_DATE is not null
    AND RECEIVED_DATE <= D.CENSUS_DATE
    AND SCHEDULED_FLAG = 'N'
    THEN 'Y'
    ELSE 'N'
    END
    FROM TBL_DATA D
    INNER JOIN TBL_PUBLISH V
    ON D.ID = V.ID
    AND D.CENSUS_DATE = V.CENSUS_DATE
    AND D.VERSION_NUMBER = V.VERSION_NUMBER
    LEFT JOIN TBL_CAT_MAP C
    ON D.SRC_CATEGORY = C.SOURCE_CAT


    Working code:



    UPDATE D
    SET PUBLISH_FLAG = 'Y'
    FROM TBL_DATA D
    INNER JOIN TBL_PUBLISH V
    ON D.ID = V.ID
    AND D.CENSUS_DATE = V.CENSUS_DATE
    AND D.VERSION_NUMBER = V.VERSION_NUMBER
    LEFT JOIN TBL_CAT_MAP C
    ON D.SRC_CATEGORY = C.SOURCE_CAT
    WHERE
    MAPPED_CAT NOT IN(1,2,3)
    AND SRC != '999'
    AND RECEIVED_DATE is not null
    AND RECEIVED_DATE <= D.CENSUS_DATE
    AND SCHEDULED_FLAG = 'N'



    I thought that both should produce exactly the same results? What am I missing?



    To help clarify the below code has 2 shows the difference, the 'PUBLISH_FLAG' column (updated using either my original code or PSK's answer) has 10162 'Y' values (the rest 'N'), the pub_2 column has the correct 18917 'Y' values.



    SELECT
    PUBLISH_FLAG,
    CASE WHEN
    MAPPED_CAT NOT IN(1,2,3)
    AND SRC != '999'
    AND RECEIVED_DATE is not null
    AND RECEIVED_DATE <= D.CENSUS_DATE
    AND SCHEDULED_FLAG = 'N'
    THEN 'Y'
    ELSE 'N'
    END as pub_2
    FROM TBL_DATA D
    INNER JOIN TBL_PUBLISH V
    ON D.ID = V.ID
    AND D.CENSUS_DATE = V.CENSUS_DATE
    AND D.VERSION_NUMBER = V.VERSION_NUMBER
    LEFT JOIN TBL_CAT_MAP C
    ON D.SRC_CATEGORY = C.SOURCE_CAT
    WHERE
    CASE WHEN
    MAPPED_CAT NOT IN(1,2,3)
    AND SRC != '999'
    AND RECEIVED_DATE is not null
    AND RECEIVED_DATE <= D.CENSUS_DATE
    AND SCHEDULED_FLAG = 'N'
    THEN 'Y'
    ELSE 'N'
    END = 'Y'









    share|improve this question


























      3












      3








      3








      I created a query to update a flag, I used a CASE statement to determine the value. However when I run the query as an UPDATE statement only about half of the expected rows are updated? More interestingly I have run the exact same UPDATE query previously on the same data and it worked as expected (looking at the old vs new is what caused me to investigate).



      I tried SELECT query using the same CASE statement, I get the correct results, but switching it back to UPDATE only updates roughly half the records.



      Moving the criteria to the WHERE clause fixed the issue. It seems to be the CASE statement in the SET part that causes problems. I can't figure out why? I'd like to know so that avoid whatever mistake I've made in the future.



      Original Code:



      UPDATE D
      SET PUBLISH_FLAG =
      CASE WHEN
      MAPPED_CAT NOT IN(1,2,3)
      AND SRC != '999'
      AND RECEIVED_DATE is not null
      AND RECEIVED_DATE <= D.CENSUS_DATE
      AND SCHEDULED_FLAG = 'N'
      THEN 'Y'
      ELSE 'N'
      END
      FROM TBL_DATA D
      INNER JOIN TBL_PUBLISH V
      ON D.ID = V.ID
      AND D.CENSUS_DATE = V.CENSUS_DATE
      AND D.VERSION_NUMBER = V.VERSION_NUMBER
      LEFT JOIN TBL_CAT_MAP C
      ON D.SRC_CATEGORY = C.SOURCE_CAT


      Working code:



      UPDATE D
      SET PUBLISH_FLAG = 'Y'
      FROM TBL_DATA D
      INNER JOIN TBL_PUBLISH V
      ON D.ID = V.ID
      AND D.CENSUS_DATE = V.CENSUS_DATE
      AND D.VERSION_NUMBER = V.VERSION_NUMBER
      LEFT JOIN TBL_CAT_MAP C
      ON D.SRC_CATEGORY = C.SOURCE_CAT
      WHERE
      MAPPED_CAT NOT IN(1,2,3)
      AND SRC != '999'
      AND RECEIVED_DATE is not null
      AND RECEIVED_DATE <= D.CENSUS_DATE
      AND SCHEDULED_FLAG = 'N'



      I thought that both should produce exactly the same results? What am I missing?



      To help clarify the below code has 2 shows the difference, the 'PUBLISH_FLAG' column (updated using either my original code or PSK's answer) has 10162 'Y' values (the rest 'N'), the pub_2 column has the correct 18917 'Y' values.



      SELECT
      PUBLISH_FLAG,
      CASE WHEN
      MAPPED_CAT NOT IN(1,2,3)
      AND SRC != '999'
      AND RECEIVED_DATE is not null
      AND RECEIVED_DATE <= D.CENSUS_DATE
      AND SCHEDULED_FLAG = 'N'
      THEN 'Y'
      ELSE 'N'
      END as pub_2
      FROM TBL_DATA D
      INNER JOIN TBL_PUBLISH V
      ON D.ID = V.ID
      AND D.CENSUS_DATE = V.CENSUS_DATE
      AND D.VERSION_NUMBER = V.VERSION_NUMBER
      LEFT JOIN TBL_CAT_MAP C
      ON D.SRC_CATEGORY = C.SOURCE_CAT
      WHERE
      CASE WHEN
      MAPPED_CAT NOT IN(1,2,3)
      AND SRC != '999'
      AND RECEIVED_DATE is not null
      AND RECEIVED_DATE <= D.CENSUS_DATE
      AND SCHEDULED_FLAG = 'N'
      THEN 'Y'
      ELSE 'N'
      END = 'Y'









      share|improve this question
















      I created a query to update a flag, I used a CASE statement to determine the value. However when I run the query as an UPDATE statement only about half of the expected rows are updated? More interestingly I have run the exact same UPDATE query previously on the same data and it worked as expected (looking at the old vs new is what caused me to investigate).



      I tried SELECT query using the same CASE statement, I get the correct results, but switching it back to UPDATE only updates roughly half the records.



      Moving the criteria to the WHERE clause fixed the issue. It seems to be the CASE statement in the SET part that causes problems. I can't figure out why? I'd like to know so that avoid whatever mistake I've made in the future.



      Original Code:



      UPDATE D
      SET PUBLISH_FLAG =
      CASE WHEN
      MAPPED_CAT NOT IN(1,2,3)
      AND SRC != '999'
      AND RECEIVED_DATE is not null
      AND RECEIVED_DATE <= D.CENSUS_DATE
      AND SCHEDULED_FLAG = 'N'
      THEN 'Y'
      ELSE 'N'
      END
      FROM TBL_DATA D
      INNER JOIN TBL_PUBLISH V
      ON D.ID = V.ID
      AND D.CENSUS_DATE = V.CENSUS_DATE
      AND D.VERSION_NUMBER = V.VERSION_NUMBER
      LEFT JOIN TBL_CAT_MAP C
      ON D.SRC_CATEGORY = C.SOURCE_CAT


      Working code:



      UPDATE D
      SET PUBLISH_FLAG = 'Y'
      FROM TBL_DATA D
      INNER JOIN TBL_PUBLISH V
      ON D.ID = V.ID
      AND D.CENSUS_DATE = V.CENSUS_DATE
      AND D.VERSION_NUMBER = V.VERSION_NUMBER
      LEFT JOIN TBL_CAT_MAP C
      ON D.SRC_CATEGORY = C.SOURCE_CAT
      WHERE
      MAPPED_CAT NOT IN(1,2,3)
      AND SRC != '999'
      AND RECEIVED_DATE is not null
      AND RECEIVED_DATE <= D.CENSUS_DATE
      AND SCHEDULED_FLAG = 'N'



      I thought that both should produce exactly the same results? What am I missing?



      To help clarify the below code has 2 shows the difference, the 'PUBLISH_FLAG' column (updated using either my original code or PSK's answer) has 10162 'Y' values (the rest 'N'), the pub_2 column has the correct 18917 'Y' values.



      SELECT
      PUBLISH_FLAG,
      CASE WHEN
      MAPPED_CAT NOT IN(1,2,3)
      AND SRC != '999'
      AND RECEIVED_DATE is not null
      AND RECEIVED_DATE <= D.CENSUS_DATE
      AND SCHEDULED_FLAG = 'N'
      THEN 'Y'
      ELSE 'N'
      END as pub_2
      FROM TBL_DATA D
      INNER JOIN TBL_PUBLISH V
      ON D.ID = V.ID
      AND D.CENSUS_DATE = V.CENSUS_DATE
      AND D.VERSION_NUMBER = V.VERSION_NUMBER
      LEFT JOIN TBL_CAT_MAP C
      ON D.SRC_CATEGORY = C.SOURCE_CAT
      WHERE
      CASE WHEN
      MAPPED_CAT NOT IN(1,2,3)
      AND SRC != '999'
      AND RECEIVED_DATE is not null
      AND RECEIVED_DATE <= D.CENSUS_DATE
      AND SCHEDULED_FLAG = 'N'
      THEN 'Y'
      ELSE 'N'
      END = 'Y'






      sql sql-server tsql






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Mar 26 at 5:22







      Domanic Lagoni

















      asked Mar 26 at 4:36









      Domanic LagoniDomanic Lagoni

      184 bronze badges




      184 bronze badges






















          3 Answers
          3






          active

          oldest

          votes


















          1














          Your first query is definitely not the same as your second. In fact from what I see here I would state your update with the CASE is the correct one since it is updating both sides of the flag. The other query with the WHERE does not update the flag to N where it is supposed to. How exactly are you determining the "correct" number of updates to be expected? I think you're expecting your UPDATE statement to have as many rows updated as the SELECT statement, while this is not always the case. The JOIN you are making could produce a cartesian product depending on your filters.



          Consider the query below.



          CREATE TABLE #table1 (Field_1 INT, Field_2 VARCHAR(MAX))
          INSERT INTO
          #table1
          VALUES
          (1, 'Item A'),
          (2, 'Item B'),
          (3, 'Item C'),
          (4, 'Item D'),
          (5, 'Item E')

          CREATE TABLE #table2 (Field_1 INT, Field_2 VARCHAR(MAX))
          INSERT INTO
          #table2
          VALUES
          (1, 'Item A'),
          (1, 'Item B'),
          (2, 'Item B'),
          (2, 'Item C'),
          (3, NULL)

          -- This produces 7 rows:
          SELECT
          *
          FROM
          #table1
          LEFT JOIN
          #table2 ON #table1.[Field_1] = #table2.[Field_1]

          -- This updates 1 row. This is akin to your second query. Only one flag value is changed.
          -- You would still have to write an UPDATE statement for the 'N' flag update.
          UPDATE
          #table1
          SET
          #table1.[Field_2] = 'Y'
          FROM
          #table1
          LEFT JOIN
          #table2 ON #table1.[Field_1] = #table2.[Field_1]
          WHERE
          #table2.[Field_2] = 'Item C'

          -- Because your UPDATE statement only updates the values to 'Y' where a condition matches, only one record is changed here.
          -- The others are left untouched.
          SELECT
          *
          FROM
          #table1

          -- Now what happens if we perform the reverse UPDATE.
          UPDATE
          #table1
          SET
          #table1.[Field_2] = 'N'
          FROM
          #table1
          LEFT JOIN
          #table2 ON #table1.[Field_1] = #table2.[Field_1]
          WHERE
          NOT (#table2.[Field_2] = 'Item C')

          -- First of all we notice that we are not dealing with NULL values at all so only two records get changed to 'N'.
          -- The first record gets changed because it does not have a match on 'Item C'.
          -- The second record also gets changed because it does not have a match on 'Item C', i.e. there is at least one record without an 'Item C' match.
          -- The last three records have either no match in the JOIN or are NULL in #table2. Meaning they are not updated.
          -- This is why I'm more a fan of your CASE query, because in theory it should deal with setting everything to the correct value.
          SELECT
          *
          FROM
          #table1

          -- Let's see what would happen with a CASE statement.
          -- Since our JOIN is a cartesian product there are multiple options for #table1.Id == 2: it can be updated to both N and Y.
          -- N is chosen by T-SQL. You will see that after the UPDATE.
          SELECT
          *, CASE WHEN #table2.[Field_2] = 'Item C' THEN 'Y' ELSE 'N' END
          FROm
          #table1
          LEFT JOIN
          #table2 ON #table1.[Field_1] = #table2.[Field_1]

          -- This updates 5 rows, maybe you would have expected 7 here based on the above SELECT statement?
          -- You can also notice how it updates everything to N, that's because our CASE deals with both sides.
          -- It's either 'Y' or either 'N'. It will always touch every record it can to UPDATE it.
          -- This in contrast with an UPDATE statement which will only touch one side and because of JOIN clauses and NULL values
          -- it's entirely possible that both UPDATE statements do not touch the entire table if written incorrectly.

          -- You would have to write an UPDATE statement like this one, which comes after the first.
          --UPDATE
          -- #table1
          --SET
          -- #table1.[Field_2] = 'N'
          --FROM
          -- #table1
          --LEFT JOIN
          -- #table2 ON #table1.[Field_1] = #table2.[Field_1]
          --WHERE
          -- #table1.[Field_2] <> 'Y' OR #table1.[Field_2] IS NULL

          -- In conclusion this means that if you want to be absolutely sure you have updated all values to their correct setting: use CASE.
          -- But if you only care about setting 'Y' to the correct value: don't use CASE.
          -- If you do use CASE, make sure you are definitely performing your JOIN correct and you are calculating the correct value for both sides.
          UPDATE
          #table1
          SET
          #table1.[Field_2] = CASE WHEN #table2.[Field_2] = 'Item C' THEN 'Y' ELSE 'N' END
          FROM
          #table1
          LEFT JOIN
          #table2 ON #table1.[Field_1] = #table2.[Field_1]

          SELECT
          *
          FROM
          #table1

          DROP TABLE #table1
          DROP TABLE #table2





          share|improve this answer

























          • This is interesting I never thought of it this way, and I'll definitely look into the left join, it seems like it is most likely the issue. However, by correct results I meant I could see individual records flagged as 'N' when they should have been 'Y'. i.e. at the actual data in the table to not just totals.

            – Domanic Lagoni
            Mar 26 at 23:32











          • @DomanicLagoni Edited for further clarification. Please notify me if this does or doesn't explain the issue to you.

            – bdebaere
            Mar 27 at 6:19












          • This does a great job of explaining thanks! It was indeed the left join causing the differences between the case and where.

            – Domanic Lagoni
            Mar 27 at 23:09


















          1














          Both the queries are not the same, in the first query all the unmatched records in the switch case will be set as 'N', irrespective of their current state.



          The second query is the right approach for this type of scenario where you are updating only the required records.



          You can change your first query like following to avoid changing the unmatched records.



          UPDATE D
          SET PUBLISH_FLAG =
          CASE WHEN
          MAPPED_CAT NOT IN(1,2,3)
          AND SRC != '999'
          AND RECEIVED_DATE is not null
          AND RECEIVED_DATE <= D.CENSUS_DATE
          AND SCHEDULED_FLAG = 'N'
          THEN 'Y'
          ELSE PUBLISH_FLAG --Modified
          END
          FROM TBL_DATA D
          INNER JOIN TBL_PUBLISH V
          ON D.ID = V.ID
          AND D.CENSUS_DATE = V.CENSUS_DATE
          AND D.VERSION_NUMBER = V.VERSION_NUMBER
          LEFT JOIN TBL_CAT_MAP C
          ON D.SRC_CATEGORY = C.SOURCE_CAT


          Note: In above query, I changed the else part.






          share|improve this answer























          • This is correct, however when I run your code it still gives the incorrect number of 'Y' records compared to using the where clause? I'll edit my answer to show some results

            – Domanic Lagoni
            Mar 26 at 5:11


















          0














          it depends on you flag conditions, which you have made.



          as per your left join it will make a join to number of records but when you apply Where conditions then the records will filter out , but you apply case then number of records remain same as earlier but as per case condition only matched flag will update not all. So it is updating on half of records.






          share|improve this answer

























            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55349925%2fcase-in-update-produces-unexpected-results-fixed-when-moved-to-where-clause-wh%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            Your first query is definitely not the same as your second. In fact from what I see here I would state your update with the CASE is the correct one since it is updating both sides of the flag. The other query with the WHERE does not update the flag to N where it is supposed to. How exactly are you determining the "correct" number of updates to be expected? I think you're expecting your UPDATE statement to have as many rows updated as the SELECT statement, while this is not always the case. The JOIN you are making could produce a cartesian product depending on your filters.



            Consider the query below.



            CREATE TABLE #table1 (Field_1 INT, Field_2 VARCHAR(MAX))
            INSERT INTO
            #table1
            VALUES
            (1, 'Item A'),
            (2, 'Item B'),
            (3, 'Item C'),
            (4, 'Item D'),
            (5, 'Item E')

            CREATE TABLE #table2 (Field_1 INT, Field_2 VARCHAR(MAX))
            INSERT INTO
            #table2
            VALUES
            (1, 'Item A'),
            (1, 'Item B'),
            (2, 'Item B'),
            (2, 'Item C'),
            (3, NULL)

            -- This produces 7 rows:
            SELECT
            *
            FROM
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]

            -- This updates 1 row. This is akin to your second query. Only one flag value is changed.
            -- You would still have to write an UPDATE statement for the 'N' flag update.
            UPDATE
            #table1
            SET
            #table1.[Field_2] = 'Y'
            FROM
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]
            WHERE
            #table2.[Field_2] = 'Item C'

            -- Because your UPDATE statement only updates the values to 'Y' where a condition matches, only one record is changed here.
            -- The others are left untouched.
            SELECT
            *
            FROM
            #table1

            -- Now what happens if we perform the reverse UPDATE.
            UPDATE
            #table1
            SET
            #table1.[Field_2] = 'N'
            FROM
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]
            WHERE
            NOT (#table2.[Field_2] = 'Item C')

            -- First of all we notice that we are not dealing with NULL values at all so only two records get changed to 'N'.
            -- The first record gets changed because it does not have a match on 'Item C'.
            -- The second record also gets changed because it does not have a match on 'Item C', i.e. there is at least one record without an 'Item C' match.
            -- The last three records have either no match in the JOIN or are NULL in #table2. Meaning they are not updated.
            -- This is why I'm more a fan of your CASE query, because in theory it should deal with setting everything to the correct value.
            SELECT
            *
            FROM
            #table1

            -- Let's see what would happen with a CASE statement.
            -- Since our JOIN is a cartesian product there are multiple options for #table1.Id == 2: it can be updated to both N and Y.
            -- N is chosen by T-SQL. You will see that after the UPDATE.
            SELECT
            *, CASE WHEN #table2.[Field_2] = 'Item C' THEN 'Y' ELSE 'N' END
            FROm
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]

            -- This updates 5 rows, maybe you would have expected 7 here based on the above SELECT statement?
            -- You can also notice how it updates everything to N, that's because our CASE deals with both sides.
            -- It's either 'Y' or either 'N'. It will always touch every record it can to UPDATE it.
            -- This in contrast with an UPDATE statement which will only touch one side and because of JOIN clauses and NULL values
            -- it's entirely possible that both UPDATE statements do not touch the entire table if written incorrectly.

            -- You would have to write an UPDATE statement like this one, which comes after the first.
            --UPDATE
            -- #table1
            --SET
            -- #table1.[Field_2] = 'N'
            --FROM
            -- #table1
            --LEFT JOIN
            -- #table2 ON #table1.[Field_1] = #table2.[Field_1]
            --WHERE
            -- #table1.[Field_2] <> 'Y' OR #table1.[Field_2] IS NULL

            -- In conclusion this means that if you want to be absolutely sure you have updated all values to their correct setting: use CASE.
            -- But if you only care about setting 'Y' to the correct value: don't use CASE.
            -- If you do use CASE, make sure you are definitely performing your JOIN correct and you are calculating the correct value for both sides.
            UPDATE
            #table1
            SET
            #table1.[Field_2] = CASE WHEN #table2.[Field_2] = 'Item C' THEN 'Y' ELSE 'N' END
            FROM
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]

            SELECT
            *
            FROM
            #table1

            DROP TABLE #table1
            DROP TABLE #table2





            share|improve this answer

























            • This is interesting I never thought of it this way, and I'll definitely look into the left join, it seems like it is most likely the issue. However, by correct results I meant I could see individual records flagged as 'N' when they should have been 'Y'. i.e. at the actual data in the table to not just totals.

              – Domanic Lagoni
              Mar 26 at 23:32











            • @DomanicLagoni Edited for further clarification. Please notify me if this does or doesn't explain the issue to you.

              – bdebaere
              Mar 27 at 6:19












            • This does a great job of explaining thanks! It was indeed the left join causing the differences between the case and where.

              – Domanic Lagoni
              Mar 27 at 23:09















            1














            Your first query is definitely not the same as your second. In fact from what I see here I would state your update with the CASE is the correct one since it is updating both sides of the flag. The other query with the WHERE does not update the flag to N where it is supposed to. How exactly are you determining the "correct" number of updates to be expected? I think you're expecting your UPDATE statement to have as many rows updated as the SELECT statement, while this is not always the case. The JOIN you are making could produce a cartesian product depending on your filters.



            Consider the query below.



            CREATE TABLE #table1 (Field_1 INT, Field_2 VARCHAR(MAX))
            INSERT INTO
            #table1
            VALUES
            (1, 'Item A'),
            (2, 'Item B'),
            (3, 'Item C'),
            (4, 'Item D'),
            (5, 'Item E')

            CREATE TABLE #table2 (Field_1 INT, Field_2 VARCHAR(MAX))
            INSERT INTO
            #table2
            VALUES
            (1, 'Item A'),
            (1, 'Item B'),
            (2, 'Item B'),
            (2, 'Item C'),
            (3, NULL)

            -- This produces 7 rows:
            SELECT
            *
            FROM
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]

            -- This updates 1 row. This is akin to your second query. Only one flag value is changed.
            -- You would still have to write an UPDATE statement for the 'N' flag update.
            UPDATE
            #table1
            SET
            #table1.[Field_2] = 'Y'
            FROM
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]
            WHERE
            #table2.[Field_2] = 'Item C'

            -- Because your UPDATE statement only updates the values to 'Y' where a condition matches, only one record is changed here.
            -- The others are left untouched.
            SELECT
            *
            FROM
            #table1

            -- Now what happens if we perform the reverse UPDATE.
            UPDATE
            #table1
            SET
            #table1.[Field_2] = 'N'
            FROM
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]
            WHERE
            NOT (#table2.[Field_2] = 'Item C')

            -- First of all we notice that we are not dealing with NULL values at all so only two records get changed to 'N'.
            -- The first record gets changed because it does not have a match on 'Item C'.
            -- The second record also gets changed because it does not have a match on 'Item C', i.e. there is at least one record without an 'Item C' match.
            -- The last three records have either no match in the JOIN or are NULL in #table2. Meaning they are not updated.
            -- This is why I'm more a fan of your CASE query, because in theory it should deal with setting everything to the correct value.
            SELECT
            *
            FROM
            #table1

            -- Let's see what would happen with a CASE statement.
            -- Since our JOIN is a cartesian product there are multiple options for #table1.Id == 2: it can be updated to both N and Y.
            -- N is chosen by T-SQL. You will see that after the UPDATE.
            SELECT
            *, CASE WHEN #table2.[Field_2] = 'Item C' THEN 'Y' ELSE 'N' END
            FROm
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]

            -- This updates 5 rows, maybe you would have expected 7 here based on the above SELECT statement?
            -- You can also notice how it updates everything to N, that's because our CASE deals with both sides.
            -- It's either 'Y' or either 'N'. It will always touch every record it can to UPDATE it.
            -- This in contrast with an UPDATE statement which will only touch one side and because of JOIN clauses and NULL values
            -- it's entirely possible that both UPDATE statements do not touch the entire table if written incorrectly.

            -- You would have to write an UPDATE statement like this one, which comes after the first.
            --UPDATE
            -- #table1
            --SET
            -- #table1.[Field_2] = 'N'
            --FROM
            -- #table1
            --LEFT JOIN
            -- #table2 ON #table1.[Field_1] = #table2.[Field_1]
            --WHERE
            -- #table1.[Field_2] <> 'Y' OR #table1.[Field_2] IS NULL

            -- In conclusion this means that if you want to be absolutely sure you have updated all values to their correct setting: use CASE.
            -- But if you only care about setting 'Y' to the correct value: don't use CASE.
            -- If you do use CASE, make sure you are definitely performing your JOIN correct and you are calculating the correct value for both sides.
            UPDATE
            #table1
            SET
            #table1.[Field_2] = CASE WHEN #table2.[Field_2] = 'Item C' THEN 'Y' ELSE 'N' END
            FROM
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]

            SELECT
            *
            FROM
            #table1

            DROP TABLE #table1
            DROP TABLE #table2





            share|improve this answer

























            • This is interesting I never thought of it this way, and I'll definitely look into the left join, it seems like it is most likely the issue. However, by correct results I meant I could see individual records flagged as 'N' when they should have been 'Y'. i.e. at the actual data in the table to not just totals.

              – Domanic Lagoni
              Mar 26 at 23:32











            • @DomanicLagoni Edited for further clarification. Please notify me if this does or doesn't explain the issue to you.

              – bdebaere
              Mar 27 at 6:19












            • This does a great job of explaining thanks! It was indeed the left join causing the differences between the case and where.

              – Domanic Lagoni
              Mar 27 at 23:09













            1












            1








            1







            Your first query is definitely not the same as your second. In fact from what I see here I would state your update with the CASE is the correct one since it is updating both sides of the flag. The other query with the WHERE does not update the flag to N where it is supposed to. How exactly are you determining the "correct" number of updates to be expected? I think you're expecting your UPDATE statement to have as many rows updated as the SELECT statement, while this is not always the case. The JOIN you are making could produce a cartesian product depending on your filters.



            Consider the query below.



            CREATE TABLE #table1 (Field_1 INT, Field_2 VARCHAR(MAX))
            INSERT INTO
            #table1
            VALUES
            (1, 'Item A'),
            (2, 'Item B'),
            (3, 'Item C'),
            (4, 'Item D'),
            (5, 'Item E')

            CREATE TABLE #table2 (Field_1 INT, Field_2 VARCHAR(MAX))
            INSERT INTO
            #table2
            VALUES
            (1, 'Item A'),
            (1, 'Item B'),
            (2, 'Item B'),
            (2, 'Item C'),
            (3, NULL)

            -- This produces 7 rows:
            SELECT
            *
            FROM
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]

            -- This updates 1 row. This is akin to your second query. Only one flag value is changed.
            -- You would still have to write an UPDATE statement for the 'N' flag update.
            UPDATE
            #table1
            SET
            #table1.[Field_2] = 'Y'
            FROM
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]
            WHERE
            #table2.[Field_2] = 'Item C'

            -- Because your UPDATE statement only updates the values to 'Y' where a condition matches, only one record is changed here.
            -- The others are left untouched.
            SELECT
            *
            FROM
            #table1

            -- Now what happens if we perform the reverse UPDATE.
            UPDATE
            #table1
            SET
            #table1.[Field_2] = 'N'
            FROM
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]
            WHERE
            NOT (#table2.[Field_2] = 'Item C')

            -- First of all we notice that we are not dealing with NULL values at all so only two records get changed to 'N'.
            -- The first record gets changed because it does not have a match on 'Item C'.
            -- The second record also gets changed because it does not have a match on 'Item C', i.e. there is at least one record without an 'Item C' match.
            -- The last three records have either no match in the JOIN or are NULL in #table2. Meaning they are not updated.
            -- This is why I'm more a fan of your CASE query, because in theory it should deal with setting everything to the correct value.
            SELECT
            *
            FROM
            #table1

            -- Let's see what would happen with a CASE statement.
            -- Since our JOIN is a cartesian product there are multiple options for #table1.Id == 2: it can be updated to both N and Y.
            -- N is chosen by T-SQL. You will see that after the UPDATE.
            SELECT
            *, CASE WHEN #table2.[Field_2] = 'Item C' THEN 'Y' ELSE 'N' END
            FROm
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]

            -- This updates 5 rows, maybe you would have expected 7 here based on the above SELECT statement?
            -- You can also notice how it updates everything to N, that's because our CASE deals with both sides.
            -- It's either 'Y' or either 'N'. It will always touch every record it can to UPDATE it.
            -- This in contrast with an UPDATE statement which will only touch one side and because of JOIN clauses and NULL values
            -- it's entirely possible that both UPDATE statements do not touch the entire table if written incorrectly.

            -- You would have to write an UPDATE statement like this one, which comes after the first.
            --UPDATE
            -- #table1
            --SET
            -- #table1.[Field_2] = 'N'
            --FROM
            -- #table1
            --LEFT JOIN
            -- #table2 ON #table1.[Field_1] = #table2.[Field_1]
            --WHERE
            -- #table1.[Field_2] <> 'Y' OR #table1.[Field_2] IS NULL

            -- In conclusion this means that if you want to be absolutely sure you have updated all values to their correct setting: use CASE.
            -- But if you only care about setting 'Y' to the correct value: don't use CASE.
            -- If you do use CASE, make sure you are definitely performing your JOIN correct and you are calculating the correct value for both sides.
            UPDATE
            #table1
            SET
            #table1.[Field_2] = CASE WHEN #table2.[Field_2] = 'Item C' THEN 'Y' ELSE 'N' END
            FROM
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]

            SELECT
            *
            FROM
            #table1

            DROP TABLE #table1
            DROP TABLE #table2





            share|improve this answer















            Your first query is definitely not the same as your second. In fact from what I see here I would state your update with the CASE is the correct one since it is updating both sides of the flag. The other query with the WHERE does not update the flag to N where it is supposed to. How exactly are you determining the "correct" number of updates to be expected? I think you're expecting your UPDATE statement to have as many rows updated as the SELECT statement, while this is not always the case. The JOIN you are making could produce a cartesian product depending on your filters.



            Consider the query below.



            CREATE TABLE #table1 (Field_1 INT, Field_2 VARCHAR(MAX))
            INSERT INTO
            #table1
            VALUES
            (1, 'Item A'),
            (2, 'Item B'),
            (3, 'Item C'),
            (4, 'Item D'),
            (5, 'Item E')

            CREATE TABLE #table2 (Field_1 INT, Field_2 VARCHAR(MAX))
            INSERT INTO
            #table2
            VALUES
            (1, 'Item A'),
            (1, 'Item B'),
            (2, 'Item B'),
            (2, 'Item C'),
            (3, NULL)

            -- This produces 7 rows:
            SELECT
            *
            FROM
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]

            -- This updates 1 row. This is akin to your second query. Only one flag value is changed.
            -- You would still have to write an UPDATE statement for the 'N' flag update.
            UPDATE
            #table1
            SET
            #table1.[Field_2] = 'Y'
            FROM
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]
            WHERE
            #table2.[Field_2] = 'Item C'

            -- Because your UPDATE statement only updates the values to 'Y' where a condition matches, only one record is changed here.
            -- The others are left untouched.
            SELECT
            *
            FROM
            #table1

            -- Now what happens if we perform the reverse UPDATE.
            UPDATE
            #table1
            SET
            #table1.[Field_2] = 'N'
            FROM
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]
            WHERE
            NOT (#table2.[Field_2] = 'Item C')

            -- First of all we notice that we are not dealing with NULL values at all so only two records get changed to 'N'.
            -- The first record gets changed because it does not have a match on 'Item C'.
            -- The second record also gets changed because it does not have a match on 'Item C', i.e. there is at least one record without an 'Item C' match.
            -- The last three records have either no match in the JOIN or are NULL in #table2. Meaning they are not updated.
            -- This is why I'm more a fan of your CASE query, because in theory it should deal with setting everything to the correct value.
            SELECT
            *
            FROM
            #table1

            -- Let's see what would happen with a CASE statement.
            -- Since our JOIN is a cartesian product there are multiple options for #table1.Id == 2: it can be updated to both N and Y.
            -- N is chosen by T-SQL. You will see that after the UPDATE.
            SELECT
            *, CASE WHEN #table2.[Field_2] = 'Item C' THEN 'Y' ELSE 'N' END
            FROm
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]

            -- This updates 5 rows, maybe you would have expected 7 here based on the above SELECT statement?
            -- You can also notice how it updates everything to N, that's because our CASE deals with both sides.
            -- It's either 'Y' or either 'N'. It will always touch every record it can to UPDATE it.
            -- This in contrast with an UPDATE statement which will only touch one side and because of JOIN clauses and NULL values
            -- it's entirely possible that both UPDATE statements do not touch the entire table if written incorrectly.

            -- You would have to write an UPDATE statement like this one, which comes after the first.
            --UPDATE
            -- #table1
            --SET
            -- #table1.[Field_2] = 'N'
            --FROM
            -- #table1
            --LEFT JOIN
            -- #table2 ON #table1.[Field_1] = #table2.[Field_1]
            --WHERE
            -- #table1.[Field_2] <> 'Y' OR #table1.[Field_2] IS NULL

            -- In conclusion this means that if you want to be absolutely sure you have updated all values to their correct setting: use CASE.
            -- But if you only care about setting 'Y' to the correct value: don't use CASE.
            -- If you do use CASE, make sure you are definitely performing your JOIN correct and you are calculating the correct value for both sides.
            UPDATE
            #table1
            SET
            #table1.[Field_2] = CASE WHEN #table2.[Field_2] = 'Item C' THEN 'Y' ELSE 'N' END
            FROM
            #table1
            LEFT JOIN
            #table2 ON #table1.[Field_1] = #table2.[Field_1]

            SELECT
            *
            FROM
            #table1

            DROP TABLE #table1
            DROP TABLE #table2






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Mar 27 at 6:19

























            answered Mar 26 at 5:29









            bdebaerebdebaere

            9186 silver badges18 bronze badges




            9186 silver badges18 bronze badges












            • This is interesting I never thought of it this way, and I'll definitely look into the left join, it seems like it is most likely the issue. However, by correct results I meant I could see individual records flagged as 'N' when they should have been 'Y'. i.e. at the actual data in the table to not just totals.

              – Domanic Lagoni
              Mar 26 at 23:32











            • @DomanicLagoni Edited for further clarification. Please notify me if this does or doesn't explain the issue to you.

              – bdebaere
              Mar 27 at 6:19












            • This does a great job of explaining thanks! It was indeed the left join causing the differences between the case and where.

              – Domanic Lagoni
              Mar 27 at 23:09

















            • This is interesting I never thought of it this way, and I'll definitely look into the left join, it seems like it is most likely the issue. However, by correct results I meant I could see individual records flagged as 'N' when they should have been 'Y'. i.e. at the actual data in the table to not just totals.

              – Domanic Lagoni
              Mar 26 at 23:32











            • @DomanicLagoni Edited for further clarification. Please notify me if this does or doesn't explain the issue to you.

              – bdebaere
              Mar 27 at 6:19












            • This does a great job of explaining thanks! It was indeed the left join causing the differences between the case and where.

              – Domanic Lagoni
              Mar 27 at 23:09
















            This is interesting I never thought of it this way, and I'll definitely look into the left join, it seems like it is most likely the issue. However, by correct results I meant I could see individual records flagged as 'N' when they should have been 'Y'. i.e. at the actual data in the table to not just totals.

            – Domanic Lagoni
            Mar 26 at 23:32





            This is interesting I never thought of it this way, and I'll definitely look into the left join, it seems like it is most likely the issue. However, by correct results I meant I could see individual records flagged as 'N' when they should have been 'Y'. i.e. at the actual data in the table to not just totals.

            – Domanic Lagoni
            Mar 26 at 23:32













            @DomanicLagoni Edited for further clarification. Please notify me if this does or doesn't explain the issue to you.

            – bdebaere
            Mar 27 at 6:19






            @DomanicLagoni Edited for further clarification. Please notify me if this does or doesn't explain the issue to you.

            – bdebaere
            Mar 27 at 6:19














            This does a great job of explaining thanks! It was indeed the left join causing the differences between the case and where.

            – Domanic Lagoni
            Mar 27 at 23:09





            This does a great job of explaining thanks! It was indeed the left join causing the differences between the case and where.

            – Domanic Lagoni
            Mar 27 at 23:09













            1














            Both the queries are not the same, in the first query all the unmatched records in the switch case will be set as 'N', irrespective of their current state.



            The second query is the right approach for this type of scenario where you are updating only the required records.



            You can change your first query like following to avoid changing the unmatched records.



            UPDATE D
            SET PUBLISH_FLAG =
            CASE WHEN
            MAPPED_CAT NOT IN(1,2,3)
            AND SRC != '999'
            AND RECEIVED_DATE is not null
            AND RECEIVED_DATE <= D.CENSUS_DATE
            AND SCHEDULED_FLAG = 'N'
            THEN 'Y'
            ELSE PUBLISH_FLAG --Modified
            END
            FROM TBL_DATA D
            INNER JOIN TBL_PUBLISH V
            ON D.ID = V.ID
            AND D.CENSUS_DATE = V.CENSUS_DATE
            AND D.VERSION_NUMBER = V.VERSION_NUMBER
            LEFT JOIN TBL_CAT_MAP C
            ON D.SRC_CATEGORY = C.SOURCE_CAT


            Note: In above query, I changed the else part.






            share|improve this answer























            • This is correct, however when I run your code it still gives the incorrect number of 'Y' records compared to using the where clause? I'll edit my answer to show some results

              – Domanic Lagoni
              Mar 26 at 5:11















            1














            Both the queries are not the same, in the first query all the unmatched records in the switch case will be set as 'N', irrespective of their current state.



            The second query is the right approach for this type of scenario where you are updating only the required records.



            You can change your first query like following to avoid changing the unmatched records.



            UPDATE D
            SET PUBLISH_FLAG =
            CASE WHEN
            MAPPED_CAT NOT IN(1,2,3)
            AND SRC != '999'
            AND RECEIVED_DATE is not null
            AND RECEIVED_DATE <= D.CENSUS_DATE
            AND SCHEDULED_FLAG = 'N'
            THEN 'Y'
            ELSE PUBLISH_FLAG --Modified
            END
            FROM TBL_DATA D
            INNER JOIN TBL_PUBLISH V
            ON D.ID = V.ID
            AND D.CENSUS_DATE = V.CENSUS_DATE
            AND D.VERSION_NUMBER = V.VERSION_NUMBER
            LEFT JOIN TBL_CAT_MAP C
            ON D.SRC_CATEGORY = C.SOURCE_CAT


            Note: In above query, I changed the else part.






            share|improve this answer























            • This is correct, however when I run your code it still gives the incorrect number of 'Y' records compared to using the where clause? I'll edit my answer to show some results

              – Domanic Lagoni
              Mar 26 at 5:11













            1












            1








            1







            Both the queries are not the same, in the first query all the unmatched records in the switch case will be set as 'N', irrespective of their current state.



            The second query is the right approach for this type of scenario where you are updating only the required records.



            You can change your first query like following to avoid changing the unmatched records.



            UPDATE D
            SET PUBLISH_FLAG =
            CASE WHEN
            MAPPED_CAT NOT IN(1,2,3)
            AND SRC != '999'
            AND RECEIVED_DATE is not null
            AND RECEIVED_DATE <= D.CENSUS_DATE
            AND SCHEDULED_FLAG = 'N'
            THEN 'Y'
            ELSE PUBLISH_FLAG --Modified
            END
            FROM TBL_DATA D
            INNER JOIN TBL_PUBLISH V
            ON D.ID = V.ID
            AND D.CENSUS_DATE = V.CENSUS_DATE
            AND D.VERSION_NUMBER = V.VERSION_NUMBER
            LEFT JOIN TBL_CAT_MAP C
            ON D.SRC_CATEGORY = C.SOURCE_CAT


            Note: In above query, I changed the else part.






            share|improve this answer













            Both the queries are not the same, in the first query all the unmatched records in the switch case will be set as 'N', irrespective of their current state.



            The second query is the right approach for this type of scenario where you are updating only the required records.



            You can change your first query like following to avoid changing the unmatched records.



            UPDATE D
            SET PUBLISH_FLAG =
            CASE WHEN
            MAPPED_CAT NOT IN(1,2,3)
            AND SRC != '999'
            AND RECEIVED_DATE is not null
            AND RECEIVED_DATE <= D.CENSUS_DATE
            AND SCHEDULED_FLAG = 'N'
            THEN 'Y'
            ELSE PUBLISH_FLAG --Modified
            END
            FROM TBL_DATA D
            INNER JOIN TBL_PUBLISH V
            ON D.ID = V.ID
            AND D.CENSUS_DATE = V.CENSUS_DATE
            AND D.VERSION_NUMBER = V.VERSION_NUMBER
            LEFT JOIN TBL_CAT_MAP C
            ON D.SRC_CATEGORY = C.SOURCE_CAT


            Note: In above query, I changed the else part.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Mar 26 at 4:44









            PSKPSK

            13.5k3 gold badges18 silver badges35 bronze badges




            13.5k3 gold badges18 silver badges35 bronze badges












            • This is correct, however when I run your code it still gives the incorrect number of 'Y' records compared to using the where clause? I'll edit my answer to show some results

              – Domanic Lagoni
              Mar 26 at 5:11

















            • This is correct, however when I run your code it still gives the incorrect number of 'Y' records compared to using the where clause? I'll edit my answer to show some results

              – Domanic Lagoni
              Mar 26 at 5:11
















            This is correct, however when I run your code it still gives the incorrect number of 'Y' records compared to using the where clause? I'll edit my answer to show some results

            – Domanic Lagoni
            Mar 26 at 5:11





            This is correct, however when I run your code it still gives the incorrect number of 'Y' records compared to using the where clause? I'll edit my answer to show some results

            – Domanic Lagoni
            Mar 26 at 5:11











            0














            it depends on you flag conditions, which you have made.



            as per your left join it will make a join to number of records but when you apply Where conditions then the records will filter out , but you apply case then number of records remain same as earlier but as per case condition only matched flag will update not all. So it is updating on half of records.






            share|improve this answer



























              0














              it depends on you flag conditions, which you have made.



              as per your left join it will make a join to number of records but when you apply Where conditions then the records will filter out , but you apply case then number of records remain same as earlier but as per case condition only matched flag will update not all. So it is updating on half of records.






              share|improve this answer

























                0












                0








                0







                it depends on you flag conditions, which you have made.



                as per your left join it will make a join to number of records but when you apply Where conditions then the records will filter out , but you apply case then number of records remain same as earlier but as per case condition only matched flag will update not all. So it is updating on half of records.






                share|improve this answer













                it depends on you flag conditions, which you have made.



                as per your left join it will make a join to number of records but when you apply Where conditions then the records will filter out , but you apply case then number of records remain same as earlier but as per case condition only matched flag will update not all. So it is updating on half of records.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Mar 26 at 5:15









                Vikram SinghVikram Singh

                693 bronze badges




                693 bronze badges



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55349925%2fcase-in-update-produces-unexpected-results-fixed-when-moved-to-where-clause-wh%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

                    Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

                    Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript