CASE condition in SELECT statement in MySQL - mysql

I have CASE condition in SELECT. Below is the query condition
The query is from a view
SELECT expt_id,stain_type,control_stain, test_stain
CASE WHEN stain_type = 'Blue' THEN control_stain = 'NA'
CASE WHEN stain_type = 'Hemat' THEN test_stain = 'NA'
FROM experiment_results__view
Here the value 'NA' has to be populated for the condition of stain_type. Would appreciate your help with suggestions on how to write this query
Thanks!!

I expect you want to use something in the line:
SELECT
expt_id,
stain_type,
CASE WHEN stain_type = 'Blue' THEN 'NA' ELSE NULL END control_stain,
CASE WHEN stain_type = 'Hemat' THEN 'NA' ELSE NULL END test_stain
FROM experiment_results__view
to get your value of 'NA' into columns named control_stain and test_stain.
But if you want to override the existing value in those columns with the value 'NA' in just those cases, then use:
SELECT
expt_id,
stain_type,
CASE WHEN stain_type = 'Blue' THEN 'NA' ELSE control_stain END control_stain,
CASE WHEN stain_type = 'Hemat' THEN 'NA' ELSE test_stain END test_stain
FROM experiment_results__view
If you're intending an update of your table then you should rewrite this to:
UPDATE
experiment_results__view
SET
control_stain = CASE WHEN stain_type = 'Blue' THEN 'NA' ELSE control_stain END,
test_stain = CASE WHEN stain_type = 'Hemat' THEN 'NA' ELSE test_stain END
-- if you don't want to update the complete table add an WHERE clause
WHERE
<some condition>

you need to END each case statement
SELECT expt_id,stain_type,
CASE WHEN stain_type = 'Blue' THEN 'NA' ELSE control_stain END AS 'Control Stain'
CASE WHEN stain_type = 'Hemat' THEN 'NA' ELSE test_stain END AS 'Test Stain'
FROM experiment_results__view
if you are intending to update the table you can do an update query
UPDATE
experiment_results__view
SET
control_stain = CASE WHEN stain_type = 'Blue' THEN 'NA' ELSE control_stain END,
test_stain = CASE WHEN stain_type = 'Hemat' THEN 'NA' ELSE test_stain END

Related

Why mysql case condition not working correctly

I have the following code
set #string:='11';
select CASE #string
WHEN CAST(#a AS SIGNED)=11 THEN 'yes'
ELSE 'no'
END as filed;
I don't understand why it returns 'no'.
And also if I use WHEN #string='11' THEN 'yes' it also returns no.
Is this what you were aiming for?
set #string:='11';
select CASE WHEN CAST(#string AS SIGNED)='11' THEN 'yes' ELSE 'no' END as filed;
Can also be expressed as
set #string:='11';
select CASE CAST(#string AS SIGNED) when '11' THEN 'yes' ELSE 'no' END as filed;
set #string:='11';
select CASE WHEN CAST(#string AS SIGNED) = 11 THEN 'yes'
ELSE 'no'
END as filed;
Demo
Because you have not defined #a, so the value is NULL.
Hence, the ELSE clause is always going to be returned.
Then your second problem is that this does not work:
set #a = '11';
SELECT CASE #a
WHEN CAST(#a AS SIGNED) = 11 THEN 'yes'
ELSE 'no'
END as filed;
This is because CAST(#a AS SIGNED) = 11 is a boolean expression whose value is 0, 1 or NULL and that is never 11.
These do work:
SELECT CASE WHEN CAST(#a AS SIGNED) = 11 THEN 'yes'
ELSE 'no'
END as filed;
SELECT CASE #a WHEN 11 THEN 'yes'
ELSE 'no'
END as filed;

How to use Group By correclty?

I have this query that worked fine:
select isnull(email,'') as Email ,isnull([ERPM First Name],'')+' '+isnull([ERPM Last Name],'')[User Name],
geo,CustomerID,BusinessID,courseid, MIN (CompletionDate) [1st Training Course],
CASE WHEN COURSEID IN (37445,37644,37443,37778,37435,37733,37584,37483,37392,37817,
37259,37597,37391,37393,37792,37816,37256,37257,37258,37484,37485,37486)
THEN 'Yes' ELSE 'No'
END AS [Is it a campaing course?],
CASE WHEN CompletionDate BETWEEN '2017-03-10' AND '2017-09-03' THEN 'Yes' ELSE 'No'
END AS [During Campaign],
CASE WHEN COURSEID IN (37256,37257,37258,37484,37485,37486) AND
CompletionDate BETWEEN '2017-03-10' AND '2017-09-03' THEN 'ON Period Bonus' ELSE '-'
END AS [1st BONUS]
from vw_Training_Cube
where [Is disti or subdisti?] = 'No' and [Is test account?] = 'No'
and Email<>'0'
GROUP BY isnull(email,''),isnull([ERPM First Name],'')+' '+isnull([ERPM Last Name],''),geo,CustomerID,BusinessID,courseid,
CASE WHEN COURSEID IN (37445,37644,37443,37778,37435,37733,37584,37483,37392,
37817,37259,37597,37391,37393,37792,37816,37256,37257,37258,37484,37485,37486)
THEN 'Yes' ELSE 'No'
END,
CASE WHEN CompletionDate BETWEEN '2017-03-10' AND '2017-09-03' THEN 'Yes' ELSE 'No'
END,
CASE WHEN COURSEID IN (37256,37257,37258,37484,37485,37486) AND
CompletionDate BETWEEN '2017-03-10' AND '2017-09-03' THEN 'ON Period Bonus' ELSE '-5'
END
but now instead of grouping by email, I want to group by business id. But simply swapping the order doesnt solve the problem.
Unless you need an aggregate function such as COUNT() MIN() or MAX() then you can simplify your query by using select distinct.
SELECT DISTINCT
ISNULL(email, '')
AS Email
, ISNULL([ERPM First Name], '') + ' ' + ISNULL([ERPM Last Name], '')
[User Name]
, geo
, CustomerID
, BusinessID
, courseid
, MIN(CompletionDate) [1st Training Course]
, CASE
WHEN COURSEID IN (37445, 37644, 37443, 37778, 37435, 37733, 37584, 37483, 37392, 37817,
37259, 37597, 37391, 37393, 37792, 37816, 37256, 37257, 37258, 37484, 37485, 37486) THEN
'Yes'
ELSE
'No'
END AS [Is it a campaing course?]
, CASE
WHEN CompletionDate BETWEEN '2017-03-10' AND '2017-09-03' THEN
'Yes'
ELSE
'No'
END AS [During Campaign]
, CASE
WHEN COURSEID IN (37256, 37257, 37258, 37484, 37485, 37486) AND
CompletionDate BETWEEN '2017-03-10' AND '2017-09-03' THEN
'ON Period Bonus'
ELSE
'-'
END AS [1st BONUS]
FROM vw_Training_Cube
WHERE [Is disti or subdisti?] = 'No'
AND [Is test account?] = 'No'
AND Email <> '0'
ORDER BY BusinessID
To reduce the rows further, you also need to remove columns - OR - start using aggregate functions. e.g. the following would produce the minimum set of rows to list every BusinessID that meets the where conditions.
SELECT DISTINCT
BusinessID
FROM vw_Training_Cube
WHERE [Is disti or subdisti?] = 'No'
AND [Is test account?] = 'No'
AND Email <> '0'
ORDER BY BusinessID
;
Keep adding columns to that to see the effect on number of rows.

conditional insert into mysql

I am quite newbie with MySQL (5.1) and I don't achieve to do a conditional "insert into".
For each record, I want to insert into the same columns (1 and 2) from an empty/destination table, either 2 fields (A and B) or 2 other fields (C and D) from a source table containing several records.
Here my query:
INSERT INTO DB.table_destination(field1, field2)
SELECT
CASE
WHEN fieldAA='value1' THEN (
SELECT fieldA, fieldB
FROM DB.table_source<BR>
)
ELSE (
SELECT fieldC, fieldD
FROM DB.table_source
)
END
FROM db.table_source
Note that the fieldAA belongs to the table_source too.
I have an error around the second SELECT. Depending on some tiny changes in my script, it sometimes complains that I have more than one row.
I am stuck on that issue for a while, so I will greatly appreciate your help.
[EDIT]
Thanks a lot for your advices! It works perfectly with this simple example.
However, my study case is in the real life a bit more complex, as I have to deal with 3 source tables, including one condition (JOIN) between tables_source_1 and table_source_2, and one spatial function between table_source_1 and table_source_3.
Here my query that returns me the result from only one condition:
INSERT INTO test.OBSERVATION (CODE_INSEE,ID_SITE,LONGWGS84,LATWGS84)
SELECT
CASE METHODE_LOC WHEN '13' THEN insee_zerofill ELSE INSEE_zero END,
CASE METHODE_LOC WHEN '13' THEN '' ELSE ID_SITE END,
CASE METHODE_LOC WHEN '13' THEN GPS_TEL_LNG ELSE LONG_LIEU_DIT END,
CASE METHODE_LOC WHEN '13' THEN GPS_TEL_LAT ELSE LAT_LIEU_DIT END
FROM odk.test_insee, odk.site_clone RIGHT JOIN odk.DEMO_OISEAUX9_FULL_CORE ON odk.site_clone.ID_SITE=odk.DEMO_OISEAUX9_FULL_CORE.SITE_OBS
WHERE odk.GISWithin(GeomFromText(CONCAT('POINT(',GPS_TEL_LNG,' ',GPS_TEL_LAT,')')), SHAPE)
Tables details
1) odk.test_insee contains SHAPE (geometry used in the spatial function GISWithin) and insee_zerofill.
2) DEMO_OISEAUX9_FULL_CORE contains GPS_TEL_LNG & GPS_TEL_LAT (filled when METHODE_LOC is equal to 13), ID_SITE (filled when METHODE_LOC is different from 13).
3) odk.site_clone contains INSEE_zero, LONG_LIEU_DIT, LAT_LIEU_DIT.
I tried to set a CASE in the WHERE condition to tell it to perform the function only when ID_SITE is null, but without success so far.
Any ideas?
Thanks in advance!
[EDIT 2]
Now, it works! I should have repeated the specific condition within the CASE for EACH field to select, as followed:
SELECT
CASE METHODE_LOC WHEN '13' THEN
(SELECT insee_zerofill
FROM odk.test_insee, odk.DEMO_OISEAUX9_FULL_CORE
WHERE odk.GISWithin(GeomFromText(CONCAT('POINT(',`GPS_TEL_LNG`,' ',`GPS_TEL_LAT`,')')), SHAPE) )
ELSE
(SELECT INSEE_zero
FROM odk.site_clone RIGHT JOIN odk.DEMO_OISEAUX9_FULL_CORE
ON odk.site_clone.ID_SITE=odk.DEMO_OISEAUX9_FULL_CORE.SITE_OBS
WHERE odk.DEMO_OISEAUX9_FULL_CORE.SITE_OBS is not NULL )
END,
CASE METHODE_LOC WHEN '13' THEN ''
ELSE
(SELECT ID_SITE
FROM odk.site_clone RIGHT JOIN odk.DEMO_OISEAUX9_FULL_CORE
ON odk.site_clone.ID_SITE=odk.DEMO_OISEAUX9_FULL_CORE.SITE_OBS
WHERE odk.DEMO_OISEAUX9_FULL_CORE.SITE_OBS is not NULL )
END,
CASE METHODE_LOC WHEN '13' THEN
(SELECT GPS_TEL_LNG
FROM odk.test_insee, odk.DEMO_OISEAUX9_FULL_CORE
WHERE odk.GISWithin(GeomFromText(CONCAT('POINT(',`GPS_TEL_LNG`,' ',`GPS_TEL_LAT`,')')), SHAPE) )
ELSE
(SELECT LONG_LIEU_DIT
FROM odk.site_clone RIGHT JOIN odk.DEMO_OISEAUX9_FULL_CORE
ON odk.site_clone.ID_SITE=odk.DEMO_OISEAUX9_FULL_CORE.SITE_OBS
WHERE odk.DEMO_OISEAUX9_FULL_CORE.SITE_OBS is not NULL )
END,
CASE METHODE_LOC WHEN '13' THEN
(SELECT GPS_TEL_LAT
FROM odk.test_insee, odk.DEMO_OISEAUX9_FULL_CORE
WHERE odk.GISWithin(GeomFromText(CONCAT('POINT(',`GPS_TEL_LNG`,' ',`GPS_TEL_LAT`,')')), SHAPE) )
ELSE
(SELECT LAT_LIEU_DIT
FROM odk.site_clone RIGHT JOIN odk.DEMO_OISEAUX9_FULL_CORE
ON odk.site_clone.ID_SITE=odk.DEMO_OISEAUX9_FULL_CORE.SITE_OBS
WHERE odk.DEMO_OISEAUX9_FULL_CORE.SITE_OBS is not NULL )
END
FROM odk.DEMO_OISEAUX9_FULL_CORE ;
this wawy for case
INSERT INTO DB.table_destination(field1, field2)
SELECT CASE fieldAA WHEN 'value1' THEN fieldA ELSE fieldC END ,
CASE fieldAA WHEN 'value1' THEN fieldB ELSE fieldD END
FROM db.table_source
If i understand correctly you question and you want perform your insert select only if ID_SITE is null then you should use
INSERT INTO test.OBSERVATION (CODE_INSEE,ID_SITE,LONGWGS84,LATWGS84)
SELECT
CASE METHODE_LOC WHEN '13' THEN insee_zerofill ELSE INSEE_zero END,
CASE METHODE_LOC WHEN '13' THEN '' ELSE ID_SITE END,
CASE METHODE_LOC WHEN '13' THEN GPS_TEL_LNG ELSE LONG_LIEU_DIT END,
CASE METHODE_LOC WHEN '13' THEN GPS_TEL_LAT ELSE LAT_LIEU_DIT END
FROM odk.test_insee, odk.site_clone RIGHT JOIN odk.DEMO_OISEAUX9_FULL_CORE ON odk.site_clone.ID_SITE=odk.DEMO_OISEAUX9_FULL_CORE.SITE_OBS
WHERE odk.GISWithin(GeomFromText(CONCAT('POINT(',GPS_TEL_LNG,' ',GPS_TEL_LAT,')')), SHAPE)
AND ID_SITE is null ;
you can use both case when is null
INSERT INTO DB.table_destination(field1, field2)
SELECT CASE fieldAA WHEN is null THEN fieldA ELSE fieldC END ,
CASE fieldAA WHEN 'value1' THEN fieldB ELSE fieldD END
FROM db.table_source
or ifnull
INSERT INTO DB.table_destination(field1, field2)
SELECT ifnull( fieldAA, your_column_for_null) ,
CASE fieldAA WHEN 'value1' THEN fieldB ELSE fieldD END
FROM db.table_source

not retrieving exact result from case statement

I am using below query but Y column not retrieving exact result. Could you guys please help me out
SELECT FAPI.*,
CASE WHEN (SELECT DISTINCT 'Y'
FROM FLOOR_PI FAPI,
NUATON NUMF
WHERE FAPI.BRCH = NUMF.BRCH
AND FAPI.BASE = NUMF.BASE
AND FAPI.NUM = 0
AND NVL(FAPI.RATION, 'X') <> 'D'
AND FAPI.CODE = 'A'
AND NUMF.R_DATE
BETWEEN FAPI.EFF_DATE
AND FAPI.EXP_DATE ) = 'Y'
THEN 'Y'
ELSE 'N' END NEW
FROM FLOOR_PI FAPI
Thank you,
Rave
Based on #SlimsGohst comment:
You should replace FAPIx with FAPI1 or FAPI2 whichever is applicable
SELECT FAPI1.*,
CASE WHEN (SELECT DISTINCT 'Y'
FROM FLOOR_PI FAPI2,
NUATON NUMF
WHERE FAPIx.BRCH = NUMF.BRCH
AND FAPIx.BASE = NUMF.BASE
AND FAPIx.NUM = 0
AND NVL(FAPIx.RATION, 'X') <> 'D'
AND FAPIx.CODE = 'A'
AND NUMF.R_DATE
BETWEEN FAPIx.EFF_DATE
AND FAPIx.EXP_DATE ) = 'Y'
THEN 'Y'
ELSE 'N' END NEW
FROM FLOOR_PI FAPI1

sql Alias Column Name for Use in CASE Statement

I have an sql query as below,
select Site,DataSource,
(SELECT CASE
WHEN DataSource = 'RFQ' THEN 'ChangeOperator'
ELSE 'SameOperator'
END) AS OperatorScenario,
(SELECT CASE
WHEN OperatorScenario = 'ChangeOperator' THEN '1'
ELSE '022'
END) AS OperatorScenario2
from tablename
when i execute this query i am getting exception as Invalid column name OperatorScenario. So i tried to use single codes in alias name in second query as below,
(SELECT CASE
WHEN 'OperatorScenario' = 'ChangeOperator' THEN '1'
ELSE '022'
END) AS OperatorScenario2
So then it executes always else part. Please give me some suggesssions.
Regards
sangeetha
The main issue is you cannot reference an alias in the same query. Also you have parentheses and an extra SELECT keyword, making what looks like a subquery where I don't believe you intended one (you do not have a FROM clause).
You can either copy the whole thing again (fixing your query in the process):
SELECT Site, DataSource,
CASE
WHEN DataSource = 'RFQ' THEN 'ChangeOperator'
ELSE 'SameOperator'
END AS OperatorScenario,
CASE
WHEN
CASE
WHEN DataSource = 'RFQ' THEN 'ChangeOperator'
ELSE 'SameOperator'
END = 'ChangeOperator' THEN '1'
ELSE '022'
END AS OperatorScenario2
from tablename
Or, simplifying:
SELECT Site, DataSource,
CASE
WHEN DataSource = 'RFQ' THEN 'ChangeOperator'
ELSE 'SameOperator'
END AS OperatorScenario,
CASE
WHEN DataSource = 'RFQ' THEN '1'
ELSE '022'
END AS OperatorScenario2
from tablename
Or use a CTE (again fixing your query):
WITH cte AS
(
SELECT Site, DataSource,
CASE
WHEN DataSource = 'RFQ' THEN 'ChangeOperator'
ELSE 'SameOperator'
END AS OperatorScenario,
FROM tablename
)
SELECT Site, DataSource, OperatorScenario,
CASE
WHEN OperatorScenario = 'ChangeOperator' THEN '1'
ELSE '022'
END AS OperatorScenario2
FROM cte
You cannot access the alias on the same level in this query, either use a sub-query or a cte:
WITH cte
AS (SELECT site,
datasource,
CASE
WHEN datasource = 'RFQ' THEN 'ChangeOperator'
ELSE 'SameOperator'
END AS OperatorScenario
FROM dbo.tablename)
SELECT site,
datasource,
operatorscenario,
CASE
WHEN operatorscenario = 'ChangeOperator' THEN '1'
ELSE '022'
END AS OperatorScenario2
FROM cte
Note that i've also removed the extra parantheses and select in the CASE.
I set my aliases at the beginning like this:
SELECT [ALIAS] = CASE....
Yours would be:
SELECT Site, DataSource,
[OperatorScenario] = CASE
WHEN DataSource = 'RFQ' THEN 'ChangeOperator' ELSE 'SameOperator'
END,
[OperatorScenario2] = CASE
WHEN DataSource = 'RFQ' THEN '1' ELSE '022'
END
from tablename