Alternative to Complicated Case Statement












1















I'm sure I'm doing this wrong, but I can't find what the common-sense alternative is.



My input is a complicated long string field that I need to break out into other fields.



I was using a case statement, but it's ballooning into hundreds of variations. Basically repeated versions of what's below except each of them are growing to hundreds of lines long. It's a pain to update when things change and get added.



SET `BrandName` =
CASE
WHEN `SaleString` like '%Posh%' THEN 'Posh Purchaser'
WHEN `SaleString` like '%DFM%' THEN 'Deep Fried Meat'
WHEN `SaleString` like '%Glam%' THEN 'Glamour Girl'
-- [WHEN search_condition THEN statement_list] ...
ELSE NULL
END


Is there a way to use a translation table that contains to substring/value pairs?



Some thing like...



UPDATE `Sales`
SET `BrandName` = `translation`.`value`
WHERE '%substring%' = `translation`.`clue`;


Edit:



This answer from Bill works perfectly for me. Thanks ya'll.



UPDATE Sales s
JOIN Translation t ON s.SaleString LIKE CONCAT('%', t.clue, '%')
SET s.BrandName = t.value









share|improve this question

























  • I advice you to read Why should I provide an MCVE for what seems to me to be a very simple SQL query?

    – Raymond Nijland
    Nov 17 '18 at 19:23











  • ELSE NULL ?? that looks wierd because that updates the complete column BrandName to NULL when there is no match in that record... Normally you would write ELSE BrandName to keep the correct data..

    – Raymond Nijland
    Nov 17 '18 at 19:27













  • The ELSE NULL was there because the default value of BrandName is NULL. I can see why your version would be better.

    – user1110771
    Nov 17 '18 at 20:24
















1















I'm sure I'm doing this wrong, but I can't find what the common-sense alternative is.



My input is a complicated long string field that I need to break out into other fields.



I was using a case statement, but it's ballooning into hundreds of variations. Basically repeated versions of what's below except each of them are growing to hundreds of lines long. It's a pain to update when things change and get added.



SET `BrandName` =
CASE
WHEN `SaleString` like '%Posh%' THEN 'Posh Purchaser'
WHEN `SaleString` like '%DFM%' THEN 'Deep Fried Meat'
WHEN `SaleString` like '%Glam%' THEN 'Glamour Girl'
-- [WHEN search_condition THEN statement_list] ...
ELSE NULL
END


Is there a way to use a translation table that contains to substring/value pairs?



Some thing like...



UPDATE `Sales`
SET `BrandName` = `translation`.`value`
WHERE '%substring%' = `translation`.`clue`;


Edit:



This answer from Bill works perfectly for me. Thanks ya'll.



UPDATE Sales s
JOIN Translation t ON s.SaleString LIKE CONCAT('%', t.clue, '%')
SET s.BrandName = t.value









share|improve this question

























  • I advice you to read Why should I provide an MCVE for what seems to me to be a very simple SQL query?

    – Raymond Nijland
    Nov 17 '18 at 19:23











  • ELSE NULL ?? that looks wierd because that updates the complete column BrandName to NULL when there is no match in that record... Normally you would write ELSE BrandName to keep the correct data..

    – Raymond Nijland
    Nov 17 '18 at 19:27













  • The ELSE NULL was there because the default value of BrandName is NULL. I can see why your version would be better.

    – user1110771
    Nov 17 '18 at 20:24














1












1








1








I'm sure I'm doing this wrong, but I can't find what the common-sense alternative is.



My input is a complicated long string field that I need to break out into other fields.



I was using a case statement, but it's ballooning into hundreds of variations. Basically repeated versions of what's below except each of them are growing to hundreds of lines long. It's a pain to update when things change and get added.



SET `BrandName` =
CASE
WHEN `SaleString` like '%Posh%' THEN 'Posh Purchaser'
WHEN `SaleString` like '%DFM%' THEN 'Deep Fried Meat'
WHEN `SaleString` like '%Glam%' THEN 'Glamour Girl'
-- [WHEN search_condition THEN statement_list] ...
ELSE NULL
END


Is there a way to use a translation table that contains to substring/value pairs?



Some thing like...



UPDATE `Sales`
SET `BrandName` = `translation`.`value`
WHERE '%substring%' = `translation`.`clue`;


Edit:



This answer from Bill works perfectly for me. Thanks ya'll.



UPDATE Sales s
JOIN Translation t ON s.SaleString LIKE CONCAT('%', t.clue, '%')
SET s.BrandName = t.value









share|improve this question
















I'm sure I'm doing this wrong, but I can't find what the common-sense alternative is.



My input is a complicated long string field that I need to break out into other fields.



I was using a case statement, but it's ballooning into hundreds of variations. Basically repeated versions of what's below except each of them are growing to hundreds of lines long. It's a pain to update when things change and get added.



SET `BrandName` =
CASE
WHEN `SaleString` like '%Posh%' THEN 'Posh Purchaser'
WHEN `SaleString` like '%DFM%' THEN 'Deep Fried Meat'
WHEN `SaleString` like '%Glam%' THEN 'Glamour Girl'
-- [WHEN search_condition THEN statement_list] ...
ELSE NULL
END


Is there a way to use a translation table that contains to substring/value pairs?



Some thing like...



UPDATE `Sales`
SET `BrandName` = `translation`.`value`
WHERE '%substring%' = `translation`.`clue`;


Edit:



This answer from Bill works perfectly for me. Thanks ya'll.



UPDATE Sales s
JOIN Translation t ON s.SaleString LIKE CONCAT('%', t.clue, '%')
SET s.BrandName = t.value






mysql






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 17 '18 at 20:26







user1110771

















asked Nov 17 '18 at 19:21









user1110771user1110771

225




225













  • I advice you to read Why should I provide an MCVE for what seems to me to be a very simple SQL query?

    – Raymond Nijland
    Nov 17 '18 at 19:23











  • ELSE NULL ?? that looks wierd because that updates the complete column BrandName to NULL when there is no match in that record... Normally you would write ELSE BrandName to keep the correct data..

    – Raymond Nijland
    Nov 17 '18 at 19:27













  • The ELSE NULL was there because the default value of BrandName is NULL. I can see why your version would be better.

    – user1110771
    Nov 17 '18 at 20:24



















  • I advice you to read Why should I provide an MCVE for what seems to me to be a very simple SQL query?

    – Raymond Nijland
    Nov 17 '18 at 19:23











  • ELSE NULL ?? that looks wierd because that updates the complete column BrandName to NULL when there is no match in that record... Normally you would write ELSE BrandName to keep the correct data..

    – Raymond Nijland
    Nov 17 '18 at 19:27













  • The ELSE NULL was there because the default value of BrandName is NULL. I can see why your version would be better.

    – user1110771
    Nov 17 '18 at 20:24

















I advice you to read Why should I provide an MCVE for what seems to me to be a very simple SQL query?

– Raymond Nijland
Nov 17 '18 at 19:23





I advice you to read Why should I provide an MCVE for what seems to me to be a very simple SQL query?

– Raymond Nijland
Nov 17 '18 at 19:23













ELSE NULL ?? that looks wierd because that updates the complete column BrandName to NULL when there is no match in that record... Normally you would write ELSE BrandName to keep the correct data..

– Raymond Nijland
Nov 17 '18 at 19:27







ELSE NULL ?? that looks wierd because that updates the complete column BrandName to NULL when there is no match in that record... Normally you would write ELSE BrandName to keep the correct data..

– Raymond Nijland
Nov 17 '18 at 19:27















The ELSE NULL was there because the default value of BrandName is NULL. I can see why your version would be better.

– user1110771
Nov 17 '18 at 20:24





The ELSE NULL was there because the default value of BrandName is NULL. I can see why your version would be better.

– user1110771
Nov 17 '18 at 20:24












2 Answers
2






active

oldest

votes


















0














You need to use a join to your translation table to match each SaleString to the right row. Once you do that, set the BrandName to the corresponding value.



UPDATE Sales s
JOIN Translation t ON s.SaleString LIKE CONCAT('%', t.clue, '%')
SET s.BrandName = t.value


Note that this will do something slightly different from your CASE solution, if there are any SaleString values that match multiple patterns. Your CASE solution would set the BrandName based on the first matched pattern, but the JOIN solution will match to all of the patterns, and set the BrandName to each one, one by one.



Example: If your SaleString is "Posh Glam", it matches two patterns. The JOIN will process the SaleString twice, once for each match. First it will set the BrandName to "Posh Purchaser" on that row of Sales, then it will find the second match and overwrite the BrandName to "Glamour Girl".






share|improve this answer
























  • This worked perfectly. Thanks so much for the help. I hadn't thought to write the concat to make it work.

    – user1110771
    Nov 17 '18 at 20:22



















1














Most simple and something which costs less maintenance or changing complete switches.

Would be to create a (temporary) table where you keep the patterns and replaces.

If somethings changes you can just INSERT, UPDATE or DELETE the records from the table.



Create table and insert's



CREATE TABLE update_sales (

pattern VARCHAR(255)
, replace_with VARCHAR(255)
);

INSERT INTO update_sales (pattern, replace_with) VALUES('Posh', 'Posh Purchaser');
INSERT INTO update_sales (pattern, replace_with) VALUES('DFM', 'Deep Fried Meat');
INSERT INTO update_sales (pattern, replace_with) VALUES('Glam', 'Glamour Girl');


And use the following query..



Query



UPDATE 
Sales
INNER JOIN
update_sales
ON
Sales.SaleString LIKE CONCAT('%', update_sales.pattern , '%')
SET
Sales.SaleString = update_sales.replace_with


Results



    SELECT * FROM Sales;

| SaleString |
| --------------- |
| Posh Purchaser |
| Deep Fried Meat |
| Glamour Girl |


demo






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%2f53354702%2falternative-to-complicated-case-statement%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    You need to use a join to your translation table to match each SaleString to the right row. Once you do that, set the BrandName to the corresponding value.



    UPDATE Sales s
    JOIN Translation t ON s.SaleString LIKE CONCAT('%', t.clue, '%')
    SET s.BrandName = t.value


    Note that this will do something slightly different from your CASE solution, if there are any SaleString values that match multiple patterns. Your CASE solution would set the BrandName based on the first matched pattern, but the JOIN solution will match to all of the patterns, and set the BrandName to each one, one by one.



    Example: If your SaleString is "Posh Glam", it matches two patterns. The JOIN will process the SaleString twice, once for each match. First it will set the BrandName to "Posh Purchaser" on that row of Sales, then it will find the second match and overwrite the BrandName to "Glamour Girl".






    share|improve this answer
























    • This worked perfectly. Thanks so much for the help. I hadn't thought to write the concat to make it work.

      – user1110771
      Nov 17 '18 at 20:22
















    0














    You need to use a join to your translation table to match each SaleString to the right row. Once you do that, set the BrandName to the corresponding value.



    UPDATE Sales s
    JOIN Translation t ON s.SaleString LIKE CONCAT('%', t.clue, '%')
    SET s.BrandName = t.value


    Note that this will do something slightly different from your CASE solution, if there are any SaleString values that match multiple patterns. Your CASE solution would set the BrandName based on the first matched pattern, but the JOIN solution will match to all of the patterns, and set the BrandName to each one, one by one.



    Example: If your SaleString is "Posh Glam", it matches two patterns. The JOIN will process the SaleString twice, once for each match. First it will set the BrandName to "Posh Purchaser" on that row of Sales, then it will find the second match and overwrite the BrandName to "Glamour Girl".






    share|improve this answer
























    • This worked perfectly. Thanks so much for the help. I hadn't thought to write the concat to make it work.

      – user1110771
      Nov 17 '18 at 20:22














    0












    0








    0







    You need to use a join to your translation table to match each SaleString to the right row. Once you do that, set the BrandName to the corresponding value.



    UPDATE Sales s
    JOIN Translation t ON s.SaleString LIKE CONCAT('%', t.clue, '%')
    SET s.BrandName = t.value


    Note that this will do something slightly different from your CASE solution, if there are any SaleString values that match multiple patterns. Your CASE solution would set the BrandName based on the first matched pattern, but the JOIN solution will match to all of the patterns, and set the BrandName to each one, one by one.



    Example: If your SaleString is "Posh Glam", it matches two patterns. The JOIN will process the SaleString twice, once for each match. First it will set the BrandName to "Posh Purchaser" on that row of Sales, then it will find the second match and overwrite the BrandName to "Glamour Girl".






    share|improve this answer













    You need to use a join to your translation table to match each SaleString to the right row. Once you do that, set the BrandName to the corresponding value.



    UPDATE Sales s
    JOIN Translation t ON s.SaleString LIKE CONCAT('%', t.clue, '%')
    SET s.BrandName = t.value


    Note that this will do something slightly different from your CASE solution, if there are any SaleString values that match multiple patterns. Your CASE solution would set the BrandName based on the first matched pattern, but the JOIN solution will match to all of the patterns, and set the BrandName to each one, one by one.



    Example: If your SaleString is "Posh Glam", it matches two patterns. The JOIN will process the SaleString twice, once for each match. First it will set the BrandName to "Posh Purchaser" on that row of Sales, then it will find the second match and overwrite the BrandName to "Glamour Girl".







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 17 '18 at 19:45









    Bill KarwinBill Karwin

    374k61513667




    374k61513667













    • This worked perfectly. Thanks so much for the help. I hadn't thought to write the concat to make it work.

      – user1110771
      Nov 17 '18 at 20:22



















    • This worked perfectly. Thanks so much for the help. I hadn't thought to write the concat to make it work.

      – user1110771
      Nov 17 '18 at 20:22

















    This worked perfectly. Thanks so much for the help. I hadn't thought to write the concat to make it work.

    – user1110771
    Nov 17 '18 at 20:22





    This worked perfectly. Thanks so much for the help. I hadn't thought to write the concat to make it work.

    – user1110771
    Nov 17 '18 at 20:22













    1














    Most simple and something which costs less maintenance or changing complete switches.

    Would be to create a (temporary) table where you keep the patterns and replaces.

    If somethings changes you can just INSERT, UPDATE or DELETE the records from the table.



    Create table and insert's



    CREATE TABLE update_sales (

    pattern VARCHAR(255)
    , replace_with VARCHAR(255)
    );

    INSERT INTO update_sales (pattern, replace_with) VALUES('Posh', 'Posh Purchaser');
    INSERT INTO update_sales (pattern, replace_with) VALUES('DFM', 'Deep Fried Meat');
    INSERT INTO update_sales (pattern, replace_with) VALUES('Glam', 'Glamour Girl');


    And use the following query..



    Query



    UPDATE 
    Sales
    INNER JOIN
    update_sales
    ON
    Sales.SaleString LIKE CONCAT('%', update_sales.pattern , '%')
    SET
    Sales.SaleString = update_sales.replace_with


    Results



        SELECT * FROM Sales;

    | SaleString |
    | --------------- |
    | Posh Purchaser |
    | Deep Fried Meat |
    | Glamour Girl |


    demo






    share|improve this answer




























      1














      Most simple and something which costs less maintenance or changing complete switches.

      Would be to create a (temporary) table where you keep the patterns and replaces.

      If somethings changes you can just INSERT, UPDATE or DELETE the records from the table.



      Create table and insert's



      CREATE TABLE update_sales (

      pattern VARCHAR(255)
      , replace_with VARCHAR(255)
      );

      INSERT INTO update_sales (pattern, replace_with) VALUES('Posh', 'Posh Purchaser');
      INSERT INTO update_sales (pattern, replace_with) VALUES('DFM', 'Deep Fried Meat');
      INSERT INTO update_sales (pattern, replace_with) VALUES('Glam', 'Glamour Girl');


      And use the following query..



      Query



      UPDATE 
      Sales
      INNER JOIN
      update_sales
      ON
      Sales.SaleString LIKE CONCAT('%', update_sales.pattern , '%')
      SET
      Sales.SaleString = update_sales.replace_with


      Results



          SELECT * FROM Sales;

      | SaleString |
      | --------------- |
      | Posh Purchaser |
      | Deep Fried Meat |
      | Glamour Girl |


      demo






      share|improve this answer


























        1












        1








        1







        Most simple and something which costs less maintenance or changing complete switches.

        Would be to create a (temporary) table where you keep the patterns and replaces.

        If somethings changes you can just INSERT, UPDATE or DELETE the records from the table.



        Create table and insert's



        CREATE TABLE update_sales (

        pattern VARCHAR(255)
        , replace_with VARCHAR(255)
        );

        INSERT INTO update_sales (pattern, replace_with) VALUES('Posh', 'Posh Purchaser');
        INSERT INTO update_sales (pattern, replace_with) VALUES('DFM', 'Deep Fried Meat');
        INSERT INTO update_sales (pattern, replace_with) VALUES('Glam', 'Glamour Girl');


        And use the following query..



        Query



        UPDATE 
        Sales
        INNER JOIN
        update_sales
        ON
        Sales.SaleString LIKE CONCAT('%', update_sales.pattern , '%')
        SET
        Sales.SaleString = update_sales.replace_with


        Results



            SELECT * FROM Sales;

        | SaleString |
        | --------------- |
        | Posh Purchaser |
        | Deep Fried Meat |
        | Glamour Girl |


        demo






        share|improve this answer













        Most simple and something which costs less maintenance or changing complete switches.

        Would be to create a (temporary) table where you keep the patterns and replaces.

        If somethings changes you can just INSERT, UPDATE or DELETE the records from the table.



        Create table and insert's



        CREATE TABLE update_sales (

        pattern VARCHAR(255)
        , replace_with VARCHAR(255)
        );

        INSERT INTO update_sales (pattern, replace_with) VALUES('Posh', 'Posh Purchaser');
        INSERT INTO update_sales (pattern, replace_with) VALUES('DFM', 'Deep Fried Meat');
        INSERT INTO update_sales (pattern, replace_with) VALUES('Glam', 'Glamour Girl');


        And use the following query..



        Query



        UPDATE 
        Sales
        INNER JOIN
        update_sales
        ON
        Sales.SaleString LIKE CONCAT('%', update_sales.pattern , '%')
        SET
        Sales.SaleString = update_sales.replace_with


        Results



            SELECT * FROM Sales;

        | SaleString |
        | --------------- |
        | Posh Purchaser |
        | Deep Fried Meat |
        | Glamour Girl |


        demo







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 17 '18 at 19:42









        Raymond NijlandRaymond Nijland

        7,98721328




        7,98721328






























            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%2f53354702%2falternative-to-complicated-case-statement%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

            Guess what letter conforming each word

            Port of Spain

            Run scheduled task as local user group (not BUILTIN)