MYSQL - UPDATE multiple fields based on single CASE statement - mysql

OBJECTIVE
I am looking for a way to update one or both fields using the same CASE statement
UPDATE vendor
SET special_cost =
(
CASE
WHEN
cost > 14
THEN
14
ELSE
SET special_cost = cost, cost = 14
END
)
WHERE upc = '12345678912345'
LOGIC
This is some logic that explains what I want to happen above.
if ($cost > 14) {
$special_cost = 14;
} else {
$special_cost = $cost;
$cost = 14;
}
It does not seem that there is a way to do this with a single CASE statement. Perhaps, this can be done with the mysql IF statement?

You are referring to case expressions not case statements.
You appear to want something like this:
UPDATE vendor
SET special_cost = GREATEST(cost, 14),
cost = 14
WHERE upc = '12345678912345';

Related

How to assign column value to a variable within mySQL script ?

I have the following script but it returns null all the time.
SELECT
#PRICE_LARGE_PRICE = PRICE_LARGE_PRICE,
#PRICE_SMALL_PRICE = PRICE_SMALL_PRICE
FROM
prices
WHERE
PRICE_LISTING_ID = 60;
SET #ITEM_PRICE = (CASE Size WHEN GivenLargeSizeName THEN #PRICE_LARGE_PRICE
WHEN GivenSmallSizeName THEN #PRICE_SMALL_PRICE
ELSE null
END);
The issue here is
#PRICE_LARGE_PRICE = PRICE_LARGE_PRICE,
#PRICE_SMALL_PRICE = PRICE_SMALL_PRICE
table returns PRICE_LARGE_PRICE & PRICE_SMALL_PRICE correctly but the assignment does not work. Hence CASE fails.
Any help is appreciated.
You need to use SELECT ... INTO:
SELECT PRICE_LARGE_PRICE, PRICE_SMALL_PRICE
INTO #PRICE_LARGE_PRICE, #PRICE_SMALL_PRICE
FROM prices
WHERE PRICE_LISTING_ID = 60;
Note that you need to ensure that the query only returns one row of data, using LIMIT 1 if necessary.
SELECT
#PRICE_LARGE_PRICE:=PRICE_LARGE_PRICE,
#PRICE_SMALL_PRICE:=PRICE_SMALL_PRICE
FROM
prices
WHERE
PRICE_LISTING_ID = 60;
just add colon before equal sign in mysql

SET inside IF in MYSQL(?)

I'm new in MYSQL and I'm trying to do this:
UPDATE team
SET member1 = IF(member1=0, 001, SET member2 = IF(member2=0, 001, member2)) WHERE ID = ?;
This is not working, explain:
Each "member" has a different number (001, 002, 003...), I want to put the member "001" in the table "member1" but if this is ocupated (it has a value different of 0) set the member "001" in the table "member2" (a diferent table) but I think is not possible to put a SET inside of an IF. The id doesn't matters.
Thanks for attention ^^
No you can't join SET statements like this. It'll have to be worked around:
UPDATE `team`
SET
`member2` = CASE WHEN `member1` = 0 AND `member2` = 0 THEN '001' ELSE `member2` END,
`member1` = CASE WHEN `member1` = 0 THEN '001' ELSE `member1` END
WHERE
`id` = ?
/* optional filter: considering adding it if it does not bother the performance: */
AND (`member1` != 0 OR `member2` != 0)
;
Notes:
I used backticks around table and column names, I recommend you do so*
I used CASE/WHEN instead of IF, because IF is not ansi sql (it is specific to mysql)
You could also do two queries instead of one. That would allow you to use a filter in the where clause, so you don't have to update the column when it's not required.
*as pointed out by Bohemian, they are not ansi. I like to use them for the structural and visual help they provide.

Is it possible to have mulitiple checks in a single mySQL IF case?

I want to write a query that will verify 8 parameters of a row are the same as the parameters passed to the procedure. If any one of them is different then modify a status, otherwise do nothing.
Is there a way I can check all those parameters in a single IF case? For example:
IF (v_duty <> duty) OR (v_current <> current) OR (v_frequency <> frequency) THEN
* UPDATE ......;
END IF
Or do I have to use an ELSE IF for each comparison I want to make?
The above doesn't work, with or without brackets between each test.
You could probably manage this with a simple UPDATE and WHERE condition:
UPDATE table_name
SET status_column = 'new_status'
WHERE identifying_column = :identifier
AND (
v_duty != :v_duty
OR v_current != :current
OR v_frequency != :frequency
)

SQL Server 2008: Error converting data type nvarchar to float

Presently troubleshooting a problem where running this SQL query:
UPDATE tblBenchmarkData
SET OriginalValue = DataValue, OriginalUnitID = DataUnitID,
DataValue = CAST(DataValue AS float) * 1.335
WHERE
FieldDataSetID = '6956beeb-a1e7-47f2-96db-0044746ad6d5'
AND ZEGCodeID IN
(SELECT ZEGCodeID FROM tblZEGCode
WHERE(ZEGCode = 'C004') OR
(LEFT(ZEGParentCode, 4) = 'C004'))
Results in the following error:
Msg 8114, Level 16, State 5, Line 1
Error converting data type nvarchar to float.
The really odd thing is, if I change the UPDATE to SELECT to inspect the values that are retrieved are numerical values:
SELECT DataValue
FROM tblBenchmarkData
WHERE FieldDataSetID = '6956beeb-a1e7-47f2-96db-0044746ad6d5'
AND ZEGCodeID IN
(SELECT ZEGCodeID
FROM tblZEGCode WHERE(ZEGCode = 'C004') OR
(LEFT(ZEGParentCode, 4) = 'C004'))
Here are the results:
DataValue
2285260
1205310
Would like to use TRY_PARSE or something like that; however, we are running on SQL Server 2008 rather than SQL Server 2012. Does anyone have any suggestions? TIA.
It would be helpful to see the schema definition of tblBenchmarkData, but you could try using ISNUMERIC in your query. Something like:
SET DataValue = CASE WHEN ISNUMERIC(DataValue)=1 THEN CAST(DataValue AS float) * 1.335
ELSE 0 END
Order of execution not always matches one's expectations.
If you set a where clause, it generally does not mean the calculations in the select list will only be applied to the rows that match that where. SQL Server may easily decide to do a bulk calculation and then filter out unwanted rows.
That said, you can easily write try_parse yourself:
create function dbo.try_parse(#v nvarchar(30))
returns float
with schemabinding, returns null on null input
as
begin
if isnumeric(#v) = 1
return cast(#v as float);
return null;
end;
So starting with your update query that's giving an error (please forgive me for rewriting it for my own clarity):
UPDATE B
SET
OriginalValue = DataValue,
OriginalUnitID = DataUnitID,
DataValue = CAST(DataValue AS float) * 1.335
FROM
dbo.tblBenchmarkData B
INNER JOIN dbo.tblZEGCode Z
ON B.ZEGCodeID = Z.ZEGCodeID
WHERE
B.FieldDataSetID = '6956beeb-a1e7-47f2-96db-0044746ad6d5'
AND (
Z.ZEGCode = 'C004' OR
Z.ZEGParentCode LIKE 'C004%'
)
I think you'll find that a SELECT statement with exactly the same expressions will give the same error:
SELECT
OriginalValue,
DataValue NewOriginalValue,
OriginalUnitID,
DataUnitID OriginalUnitID,
DataValue,
CAST(DataValue AS float) * 1.335 NewDataValue
FROM
dbo.tblBenchmarkData B
INNER JOIN dbo.tblZEGCode Z
ON B.ZEGCodeID = Z.ZEGCodeID
WHERE
B.FieldDataSetID = '6956beeb-a1e7-47f2-96db-0044746ad6d5'
AND (
Z.ZEGCode = 'C004' OR
Z.ZEGParentCode LIKE 'C004%'
)
This should show you the rows that can't convert:
SELECT
B.*
FROM
dbo.tblBenchmarkData B
INNER JOIN dbo.tblZEGCode Z
ON B.ZEGCodeID = Z.ZEGCodeID
WHERE
B.FieldDataSetID = '6956beeb-a1e7-47f2-96db-0044746ad6d5'
AND (
Z.ZEGCode = 'C004' OR
Z.ZEGParentCode LIKE 'C004%'
)
AND IsNumeric(DataValue) = 0
-- AND IsNumeric(DataValue + 'E0') = 0 -- try this if the prior doesn't work
The trick in the last commented line is to tack on things to the string to force only valid numbers to be numeric. For example, if you wanted only integers, IsNumeric(DataValue + '.0E0') = 0 would show you those that aren't.

Complex MySQL query issue

I have a somewhat complex mySQL query I am trying to execute. I have two parameters: facility and isEnabled. Facility can have a value of "ALL" or be specific ID. isEnabled can have value of "ALL" or be 0/1.
My issue is that I need to come up with logic that can handle the following scenarios:
1) Facility = ALL AND isEnabled = ALL
2) Facility = ALL AND isEnabled = value
3) Facility = someID AND isEnabled = ALL
4) Facility = someID AND isEnabled = value
The problem is that I have several nested IF statements:
IF (Facility = 'ALL') THEN
IF (isEnabled = 'ALL') THEN
SELECT * FROM myTable
ELSE
SELECT * FROM myTable
WHERE isEnabled = value
END IF;
ELSE
IF (isEnabled = 'ALL') THEN
SELECT * FROM myTable
WHERE facility = someID
ELSE
SELECT * FROM myTable
WHERE facility = someID AND isEnabled = value
END IF;
END IF;
I would like to be able to combine the logic in the WHERE clause using either a CASE statement or Conditional's (AND/OR) but I am having trouble wrapping my head around it this morning. Currently the query is not performing as it is expected to be.
Any insight would be helpful!
Thanks
You could do this...
SELECT
*
FROM
myTable
WHERE
1=1
AND (facility = someID OR Facility = 'ALL')
AND (isEnabled = value OR isEnabled = 'ALL')
However, this yields a poor execution plan - it's trying to find one size fits all, but each combination of parameters can have different plans depending on data, indexes, etc.
This means that it is better to build the query dynamically
SELECT
*
FROM
myTable
WHERE
1=1
AND facility = someID -- Only include this line if : Facility = 'ALL'
AND isEnabled = value -- Only include this line if : isEnabled = 'ALL'
I know it can feel dirty to use dynamic queries, but this is a good corner case as to when then really can excel. I'll go find a spectacularly informative link for you now. (It's a lot to read, but it's very worth learning from)
Link : Dynamic Search