Mysql CASE and UPDATE - mysql

I'm trying to do this query which updates only the first column that is empty. Here is a query so far:
UPDATE `names` SET
`name_1` = CASE WHEN `name_1` = '' then 'Jimmy' else `name_1` end,
`name_2` = CASE WHEN `name_1` != '' and `name_2` = '' then 'Jimmy' else `name_2` end
It updates all of columns with 'Jimmy'. I think that that's because the SET will update it then move on to the next SET and will update that etc...Am I right on what's causing this? If so how could I fix this? If not how should I rewrite this?

I think if you swap the order, it will work properly.
Try this:
UPDATE `names` SET
`name_2` = CASE WHEN `name_1` != '' and `name_2` = '' then 'Jimmy' else `name_2` end,
`name_1` = CASE WHEN `name_1` = '' then 'Jimmy' else `name_1` end

I'm wondering if null values might be causing you problems. You could use the IFNULL function to convert them to empty strings (in case you have empty strings and NULLs). Try this:
UPDATE `names` SET
`name_1` = CASE WHEN IFNULL(`name_1`, '') = '' then 'Jimmy' else `name_1` end,
`name_2` = CASE WHEN IFNULL(`name_1`, '') != '' and IFNULL(`name_2`, '') = '' then 'Jimmy' else `name_2` end
or if you have all nulls:
UPDATE `names` SET
`name_1` = CASE WHEN `name_1` IS NULL then 'Jimmy' else `name_1` end,
`name_2` = CASE WHEN `name_1` IS NOT NULL and `name_2` IS NULL then 'Jimmy' else `name_2` end

Related

Return a specific capture group/substring in MySQL 5 using REGEXP

I'm having trouble writing the regular expression to do what I need in MySQL syntax.
I have the following value for column http_referer in a database table:
https://www.example.com?id=123&true
And I need to return the value of the query string parameter uid (in this case, 123), to plug in to another query.
`SELECT * FROM sites WHERE id = (http_referer REGEXP 'uid=([0-9]+)&?')
This is my query, that doesn't work, probably because I'm trying to pass in a PHP-style regular expression instead of one MySQL can use (however, I understand that MySQL doesn't even support capture groups, so I'm kind of stumped).
If you use MySQL prior to version 8 which doesn't support REGEXP_REPLACE(), you can use SUBSTRING_INDEX() to extract parts of a string:
mysql> set #a = 'some.domain?id=123&true';
mysql> select substring_index( substring_index(#a, '?id=', -1), '&', 1) as result;
+--------+
| result |
+--------+
| 123 |
+--------+
If the position of the parameter whose value you are interested in is not fixed, i.e. not always the first, or if parameters following it are optional and may not be present, it's a bit more tricky and you have to add more logic.
Old topic but this solution might help for people who don't have mysql version 8.
2 notes:
You need a case set for each character. So this example is for
maximum of 3 characters (0 -999).
You can't use this solution when
your string has multiple occurrences. For example
id=123&secondid=456&anotherid=789.
SELECT
CONCAT(
CASE WHEN content LIKE '%id=?1%' THEN '1' ELSE '' END,
CASE WHEN content LIKE '%id=?2%' THEN '2' ELSE '' END,
CASE WHEN content LIKE '%id=?3%' THEN '3' ELSE '' END,
CASE WHEN content LIKE '%id=?4%' THEN '4' ELSE '' END,
CASE WHEN content LIKE '%id=?5%' THEN '5' ELSE '' END,
CASE WHEN content LIKE '%id=?6%' THEN '6' ELSE '' END,
CASE WHEN content LIKE '%id=?7%' THEN '7' ELSE '' END,
CASE WHEN content LIKE '%id=?8%' THEN '8' ELSE '' END,
CASE WHEN content LIKE '%id=?9%' THEN '9' ELSE '' END,
CASE WHEN content LIKE '%id=?0%' THEN '0' ELSE '' END,
CASE WHEN content LIKE '%id=?_1%' THEN '1' ELSE '' END,
CASE WHEN content LIKE '%id=?_2%' THEN '2' ELSE '' END,
CASE WHEN content LIKE '%id=?_3%' THEN '3' ELSE '' END,
CASE WHEN content LIKE '%id=?_4%' THEN '4' ELSE '' END,
CASE WHEN content LIKE '%id=?_5%' THEN '5' ELSE '' END,
CASE WHEN content LIKE '%id=?_6%' THEN '6' ELSE '' END,
CASE WHEN content LIKE '%id=?_7%' THEN '7' ELSE '' END,
CASE WHEN content LIKE '%id=?_8%' THEN '8' ELSE '' END,
CASE WHEN content LIKE '%id=?_9%' THEN '9' ELSE '' END,
CASE WHEN content LIKE '%id=?_0%' THEN '0' ELSE '' END,
CASE WHEN content LIKE '%id=?__1%' THEN '1' ELSE '' END,
CASE WHEN content LIKE '%id=?__2%' THEN '2' ELSE '' END,
CASE WHEN content LIKE '%id=?__3%' THEN '3' ELSE '' END,
CASE WHEN content LIKE '%id=?__4%' THEN '4' ELSE '' END,
CASE WHEN content LIKE '%id=?__5%' THEN '5' ELSE '' END,
CASE WHEN content LIKE '%id=?__6%' THEN '6' ELSE '' END,
CASE WHEN content LIKE '%id=?__7%' THEN '7' ELSE '' END,
CASE WHEN content LIKE '%id=?__8%' THEN '8' ELSE '' END,
CASE WHEN content LIKE '%id=?__9%' THEN '9' ELSE '' END,
CASE WHEN content LIKE '%id=?__0%' THEN '0' ELSE '' END
) id
FROM 'page?id=123' test WHERE test LIKE '%?id=%' and p.domain_id=18

mySQL isnull() into postgreSQL

I need to emulate the insull() function from MySQL into pgAdmin but it doesn't seem to work.
What is the PostgreSQL equivalent for ISNULL()
I tried to follow the above link but it isn't producing the results as same as MySQL. Can someone shade some light on this please.
MySQL:
(case
when
((`s`.`Funding_Date` = '')
and (isnull(`s`.`Actual_Close_Date`)
or (`s`.`Actual_Close_Date` = '')))
then
'RPG_INV'
when
((isnull(`s`.`Funding_Date`)
or (`s`.`Funding_Date` <> ''))
and ((`s`.`Actual_Close_Date` = '')
or isnull(`s`.`Actual_Close_Date`)))
then
'Builder_Inventory'
else 'Owner_Inventory'
end) AS `Lot_Status`,
pgAdmin:
case when
Funding_Date = '' and (Actual_Close_Date is null or Actual_Close_Date= '')
then 'RPG Inventory'
when (Funding_Date is null or Funding_Date <> '')
and (Actual_Close_Date = '' or Actual_Close_Date is null)
then'Builder Inventory' else 'Owner Inventory'
end as "Lot Status",

Syntax for multiple cases in MySQL

I have a MySQL update statement which is attempting to reset two columns: label and PersTrCode. (This is in a Coldfusion program.) I'm doing this with CASE statements but I can't seem to get the syntax right -- I keep getting an error. The code:
<cfquery name = 'nonull' datasource = "Moxart">
update FinAggDb
set Label = CASE
WHEN PersActIncOutg = 'I' && PersTrCode IS NULL THEN 'Total Income'
WHEN PersActIncOutg = 'O' && PersTrCode IS NULL THEN 'Total Expense'
WHEN PersActIncOutg IS NULL && PersTrCode IS NULL THEN ' '
ELSE PersTrCode
END
SET PersTrCode = CASE
WHEN PersTrCode IS NULL THEN 'Total'
ELSE PersTrCode
END
</cfquery>
The error is the usual informative statement:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SET PersTrCode = CASE WHEN PersTrCode IS NULL THEN 'Total' ELSE PersTrCode ' at line 8
Are multiple CASE statements not allowed? Or can someone tell me how to fix this?
An update statement has only one set clause, with the various columns you want to update separated by commas. Also, note that it's more common to use and and not &&, although both are valid in MySQL:
update FinAggDb
set Label = CASE
WHEN PersActIncOutg = 'I' AND PersTrCode IS NULL THEN 'Total Income'
WHEN PersActIncOutg = 'O' AND PersTrCode IS NULL THEN 'Total Expense'
WHEN PersActIncOutg IS NULL AND PersTrCode IS NULL THEN ' '
ELSE PersTrCode
END
, -- comma here, not a second "set" clause
PersTrCode = CASE
WHEN PersTrCode IS NULL THEN 'Total'
ELSE PersTrCode
END

mysql query repeats results

I have this query. I need to select the rows if logo is empty OR button is empty OR vanitylogo is empty. This seems to be working but, printing multiple rows for same mid. How to fix this ?
SELECT fmm.mid,
fmm.name ,
fmn.mnname,
fmm.button,
fmm.logo,
fmm.vanitylogo
FROM X fmm ,
Y fmn
WHERE fmm.`button` = ''
OR fmm.`button` = 'NULL'
OR fmm.`button` = 'None'
OR fmm.`logo` = ''
OR fmm.`logo` = 'NULL'
OR fmm.`logo` = 'None'
OR fmm.`vanitylogo` = ''
OR fmm.`vanitylogo` = 'NULL'
OR fmm.`vanitylogo` IS NULL
AND fmm.mid=fmn.nid
AND fmm.status='active'
AND fmm.xyz_status='active'
You have got two major problems with your query:
You have not correctly bracketed your OR conditions
You have no join condition between the tables, leading to a "cross join"
Try this:
SELECT fmm.mid,
fmm.name ,
fmn.mnname,
fmm.button,
fmm.logo,
fmm.vanitylogo
FROM X fmm
JOIN Y fmn ON fmn.some_column = X.some_column -- FIX THIS
WHERE (fmm.`button` in ('', 'NULL', 'None')
OR fmm.`logo` IN ('', 'NULL', 'None')
OR fmm.`vanitylogo` IN ('', 'NULL')
OR fmm.`vanitylogo` IS NULL)
AND fmm.mid=fmn.nid
AND fmm.status='active'
AND fmm.xyz_status='active'
You must fill in the "FIX THIS": line with the appropriate column names
Regarding the ORs, I bundled some up into IN() condition, and bracketed up the lot.
You are selecting the table 'Y fmn'. For every row in Y, the results will be repeated. You need a way to aggregate the results, possibly with a group by.
SELECT fmm.mid,
fmm.name ,
fmn.mnname,
fmm.button,
fmm.logo,
fmm.vanitylogo
FROM X fmm ,
Y fmn
WHERE fmm.`button` = ''
OR fmm.`button` = 'NULL'
OR fmm.`button` = 'None'
OR fmm.`logo` = ''
OR fmm.`logo` = 'NULL'
OR fmm.`logo` = 'None'
OR fmm.`vanitylogo` = ''
OR fmm.`vanitylogo` = 'NULL'
OR fmm.`vanitylogo` IS NULL
AND fmm.mid=fmn.nid
AND fmm.status='active'
AND fmm.xyz_status='active'
group by fmm.mid,
fmm.name ,
fmn.mnname,
fmm.button,
fmm.logo,
fmm.vanitylogo

MySQL CONCAT multiple fields with IF statement

I'm trying to do something I thought would be simple, but I'm stuck. I basically want to create a single address field from multiple address part fields, using an IF statement to use either an address or intersection. Here is my statement to make the field:
CONCAT(loc_name,'\n',
IF ( add_number != '' && add_street != '' ) THEN
CONCAT(add_number,' ',add_street,'\n')
ELSEIF ( x_street_1 != '' && x_street_2 != '' ) THEN
CONCAT(x_street_1,' & ',x_street_2,'\n')
END IF
,city,', ',
IF ( state != '') THEN
CONCAT(state,' ',country,'\n')
ELSEIF ( x_street_1 != '' && x_street_2 != '' ) THEN
CONCAT(country,'\n')
END IF
) AS loc_info
But it doesn't like what I am doing at all, it throws an error at:
"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') THEN \n\t\t\t\t\t\tadd_number,' ',add_street,'\n'\n\t\t\t\t\tELSEIF ( x_street_1 != '' && x_"
Which seems like it doesn't like my empty field ('') notation. But I don't know why. Can I not use the IF statement inside a CONCAT like that?
Thanks for any insight.
IIRC, the syntax you want to use is
IF(condition, expression_if_true, expression_if_false)
I could be wrong, but you might want to try that.
The syntax is not correct. You want to use CASE:
SET #loc_name = 'Location';
SET #add_street = 'Add Street';
SET #add_number = '10';
SET #x_street_1 = 'Street 1';
SET #x_street_2 = 'Street 2';
SET #city = 'City';
SET #state = 'State';
SET #country = 'Country';
SELECT Concat(#loc_name, '\n', CASE
WHEN #add_number != ''
AND #add_street != '' THEN
Concat(#add_number, ' ', #add_street, '\n')
WHEN #x_street_1 != ''
AND #x_street_2 != '' THEN
Concat(#x_street_1, ' & ', #x_street_2,
'\n')
end, #city, ', ', CASE
WHEN #state != '' THEN
Concat(#state, ' ', #country, '\n')
WHEN ( #x_street_1 != ''
AND #x_street_2 != '' ) THEN Concat(#country, '\n')
end) AS loc_info
Result
| LOC_INFO |
-----------------------------------------------
| Location
10 Add Street
City, State Country
|
Just find and replace # with .
this might also help:
CONCAT(loc_name,'\n',
IF ( add_number != '' && add_street != '' ,
CONCAT(add_number,' ',add_street,'\n'),
IF ( x_street_1 != '' && x_street_2 != '' ,
CONCAT(x_street_1,' & ',x_street_2,'\n'),""
)
),
city,
',' ,
IF ( state != '',
CONCAT(state,' ',country,'\n'),
IF ( x_street_1 != '' && x_street_2 != '' ,
CONCAT(country,'\n'),""
)
) AS loc_info
also what are you comparing here state != '' is it against null values?? if so this will give you incorrect answer you have to use state IS NOT NULL instead of that.