Alternative to Complicated Case Statement
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
add a comment |
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
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 toNULL
when there is no match in that record... Normally you would writeELSE BrandName
to keep the correct data..
– Raymond Nijland
Nov 17 '18 at 19:27
TheELSE NULL
was there because the default value ofBrandName
is NULL. I can see why your version would be better.
– user1110771
Nov 17 '18 at 20:24
add a comment |
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
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
mysql
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 toNULL
when there is no match in that record... Normally you would writeELSE BrandName
to keep the correct data..
– Raymond Nijland
Nov 17 '18 at 19:27
TheELSE NULL
was there because the default value ofBrandName
is NULL. I can see why your version would be better.
– user1110771
Nov 17 '18 at 20:24
add a comment |
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 toNULL
when there is no match in that record... Normally you would writeELSE BrandName
to keep the correct data..
– Raymond Nijland
Nov 17 '18 at 19:27
TheELSE NULL
was there because the default value ofBrandName
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
add a comment |
2 Answers
2
active
oldest
votes
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".
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
add a comment |
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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".
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
add a comment |
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".
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
add a comment |
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".
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".
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
add a comment |
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
add a comment |
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
add a comment |
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
add a comment |
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
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
answered Nov 17 '18 at 19:42
Raymond NijlandRaymond Nijland
7,98721328
7,98721328
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 toNULL
when there is no match in that record... Normally you would writeELSE BrandName
to keep the correct data..– Raymond Nijland
Nov 17 '18 at 19:27
The
ELSE NULL
was there because the default value ofBrandName
is NULL. I can see why your version would be better.– user1110771
Nov 17 '18 at 20:24