use Case in Where Clause SQL - sql

Hi to make this short.
I need only the column when a condition is met.
if the condition is not met, then I can proceed running my Query without that column as validation.
CONDITION NEEDED.
REFERENCE TABLE - TABLE_A
inside TABLE_A there is PARAMETER_NAME AND PARAMETER_VALUE
REQUIRED: PARAMETER_NAME= 'SMS_SEND'
PARAMETER_VALUE = 'TRUE'
COLUMN FOR VALIDATION
INSIDE TABLE_B
INVALID_STAT ---> COLUMN
IF PARAMETER_NAME= 'SMS_SEND' and PARAMETER_VALUE = 'TRUE'
THEN I NEED TO CHECK INVALID_STAT IF ITS EQUAL TO 'Y'
ELSE
I DONT NEED TO VALIDATE INVALID_STAT AT ALL
WHERE (CASE
WHEN 1 = (SELECT DECODE (PARAMETER_VALUE, 'FALSE', 1, 2)
FROM TABLE_A
WHERE PARAMETER_NAME = 'SMS_SEND')
THEN
INVALID_STAT
ELSE
'Y'
END) = 'Y'

based upon your commentary, this will get you what you have asked for.
However, I doubt this is what you need. Please update your question as requested in the commentary above. If this does answer your question, please accept it as the answer and close the question.
I expect that the real requirement will be to wrap the following query in an outer join to a larger query (which you have not supplied) along with a coalesce to deal with the possible no rows scenario.
select
case
when PARAMETER_VALUE = 'FALSE' THEN 'Y'
else ''
end as SMS_Send_Ind
from Table_A
where PARAMETER_Name = 'SMS_SEND'
;
If there is no record in the table with Parameter_name = 'SMS_SEND', then the query will return no rows. Otherwise it will a Y or a blank as determined by the number of records in Table_A with parameter_name = 'SMS_SEND'

Related

SQL case-when-else statement efficiency

When I use this statement;
UPDATE TABLE
SET FIELD = CASE
WHEN NAME = 'a' THEN (SELECT NO FROM TABLE_TWO WHERE NAME = 'a')
ELSE 'x' END
WHERE FIELD_TWO = 1
if TABLE.NAME != 'a' will the select SQL executed nevertheless?
Moreover, a little extra question, do you think it is proper to have such logic in SQL code for any given product? I think having any logic in SQL makes its coverage very difficult, and hard to maintain, what do you think?
edit: select statement only returns a single value, ignore the case where it can return multiple values, that case is not in the scope of this question.
The Oracle manual claims that it does short-circuit evaluation:
Oracle Database uses short-circuit evaluation. For a simple CASE expression, the database evaluates each comparison_expr value only before comparing it to expr, rather than evaluating all comparison_expr values before comparing any of them with expr
In your case comparison_expr is the WHEN NAME = 'a' part and if the manual is right, the database will not run the select if name has a different value.
I think it would be easier to read and maintain, when you split it into two UPDATE-statements like this:
UPDATE TABLE SET FIELD = (SELECT TOP 1 NO FROM TABLE_TWO WHERE NAME = 'a')
WHERE FIELD_TWO = 1
AND NAME='a'
UPDATE TABLE SET FIELD = 'x'
WHERE FIELD_TWO = 1
AND NAME != 'a'
It lets you add more cases easily and you can generalize the cases if there are more of them, like:
UPDATE TABLE SET FIELD = (SELECT TOP 1 NO FROM TABLE_TWO WHERE NAME = TABLE.FIELD)
WHERE FIELD_TWO = 1
AND NAME IN ('a','b','c')
If I were you, I would use a variable so that case doesn't compute a scalar value everytime. Something like following:
DECLARE #myVar VARCHAR(10);
SELECT TOP 1 #myVar = NO FROM TABLE_TWO WHERE NAME = 'a';
UPDATE TABLE
SET FIELD = CASE
WHEN NAME = 'a' THEN #myVar
ELSE 'x' END
WHERE FIELD_TWO = 1

Updating multiple columns using Case

I have a query that looks like below:
UPDATE some_table
SET column_x = CASE WHEN x_specific_condition THEN new_value_for_x ELSE column_x END,
column_y = CASE WHEN y_specific_condition THEN new_value_for_y ELSE column_y END,
WHERE some_more_conditions
Problem with above is, each column (x, y) still gets updated with their own value if some_more_conditions return true irrespective of their specific conditions returning true. I tried removing ELSE from above, but no luck
I am combining as some_more_conditions are same for both cases, I think its better to perform all in 1 update (suggestions welcome)
Do you know if there is a way that I can perform the above update in 1 query by skipping the individual columns where the specific conditions do not match (basically avoid overwriting of same values)
To do this in one update, you would need to expand the where clause:
UPDATE some_table
SET column_x = CASE WHEN x_specific_condition THEN new_value_for_x ELSE column_x END,
column_y = CASE WHEN y_specific_condition THEN new_value_for_y ELSE column_y END,
WHERE some_more_conditions AND
(x_specific_condition OR
y_specific_condition
);
An alternative is to use multiple updates, but that could be more expensive:
UPDATE some_table
SET column_x = new_value_for_x
WHERE some_more_conditions AND x_specific_condition;
UPDATE some_table
SET column_y = new_value_for_y
WHERE some_more_conditions AND y_specific_condition;
update [table_name]
set [column_name_1] = case when [column_name_1] = [condition_1] then [condition_2]
else [column_name_1]
end,
[column_name_2] = case when [column_name_2] = [condition_1] then [condition_2]
else [column_name_2]
end,
where condition;
Note: [table_name] is your table name, [column_name] is your column name in which you want to update values.
you can update values without where condition as well.
find screenshot

CASE WHEN after THEN or Select value from other table

I need to do this:
SELECT
COLUMN1,
COLUMN2,
CASE SOMETHING WHEN 0 THEN 'SOMETHING'
ELSE
CASE SOMETHING1 WHEN 'SOMETHING2' THEN (Here I need my value from other table)
ELSE
...
ELSE
...
END
END
AS SOMETHINGSPECIAL
...
...
...
Entire select is horribly complicated sorry.
In the place after THEN in () I need to take out specific value from other table.
I have tried almost everything there is from joins, to put there SELECT WHERE or CASE WHEN statement it always end up with some error.
Keyword missing etc.
Also maybe problem is inside () there is long concatenate:
''
I need to put that specific value from other table into that concatenate.
It either doesn't want to allow me to use other CASE WHEN after that THEN or I'm doing something wrong.
EDIT (sorry cant post entire query dont wanna have problems in work):
SELECT
A.SOMETHING
CASE WHEN A.LIST_ID IN ('something','something') THEN ' (MY VALUE FROM OTHER TABLE HERE) '
END
AS SOMETHINGSPECIAL
FROM SOMETABLE
...
(MY VALUE FROM OTHER TABLE HERE) I tried to put there Select statement condition, Case statement to take out that one value from other table but it just gives me error.
You can use a correlated subquery:
(CASE SOMETHING
WHEN 0 THEN 'SOMETHING'
ELSE (CASE SOMETHING1
WHEN 'SOMETHING2' THEN (select value from othertable ot where ot.col = x.col)
ELSE . . .
Do note that you don't need nested cases. You could write this as:
(CASE WHEN SOMETHING = 0 THEN 'SOMETHING'
WHEN SOMETHING1 = 'SOMETHING2' THEN (select value from othertable ot where ot.col = x.col)
ELSE . . .
END)
You could try joining the table that the other values should come from, that's if there is a link between those tables, so these is what you should do
SELECT
T1.COLUMN1,
T2.COLUMN1,
T.The-column-you-want-from-table2
iNNER JOIN TABLE2 T2 ON T2.cOUMN1 = T1.COLUMN1
So there is no need for a case statement, because from what I can gather from your question, you want a representation value of a value from another table
Here is another more specific example,
Select
Transaction.OrderId
Transaction.OrderDate
Order.StatusDescription
From Transaction
Inner Join Order on Order.OrderID = Transaction.OrderID
In the above example, the StatusDescription is what need from the "other" table, this can be anything from paid,out-of-stock or whatever status. This status in your first table is represented by a number like 1 for paid, 2 for out of stock etc.....
Hope this helps

compare data between 2 table

Hey i have a requirement to compare two tables of same structure.
Table1
EmpNO - Pkey
EmpName
DeptName
FatherName
IssueDate
ValidDate
I need to pass the EMPNO as parameter and I need to compare whether any of the column get changes? and return YES OR NO value.
can I able to do that using a PL/SQL Funcation? I was thinking of using the CONCAT in-build function to do that.
I'm trying the below one
Table1Concat = Select CONCAT(Column1.....6) from tbale1 where emp_no= in_empno;
Table2Concat = Select CONCAT(Column1.....6) from tbale2 where emp_no= in_empno;
IF(Table1Concat<>Table2Concat ) THEN return data_changed :='YES';
else data_changed :='NO';
END;
If you only want to detect whether any value is different then ...
select count(*)
from (select * from table1 where emp_no = my_emp_no
union
select * from table2 where emp_no = my_emp_no
)
If it returns 1 then the rows are the same, if it returns 2 then there is a difference.
The columns must be in the same order for this to work, or you'll have to list out all the column names in the order in which they match.
If you wanted to do this in bulk for a great many rows then you'd most likely use a different solution, s do not loop through every emp_no running this code for each one.
For bulk data where all emp_id's are present in both tables, use a query of the form:
select table1.emp_no,
case when table1.column1 = table2.column1 and
table2.column2 = table2.column2 and
table2.column3 = table2.column3 and
...
then 'Yes'
else 'No
end columns_match
from table1
join table2 on table1.emp_no = table2.emp_no
You can insert this result directly into a logging table.
Take care of null values though. "any_value = null" is never true, and "any_value != Null" is also never true, so you might need to add logic to take care of cases where one or both values are null.

Need help for bit data type

i want to write a generic sql where i want show yes or not if field data type is bit. here i need to check the data type if data type is bit then it should show yes or no based on value 0 or 1.
select stock_code,makeid,modelid,enginesize,automatic,semiautomatic,manual from VehicleInfoForParts
so in my above sql there is bit type fields are automatic,semiautomatic,manual. so here i need to show yes/no but i dont want to hard code anything.
so please guide me what would be the best approach for generic sql statement.
can i join my table with system table called information_schema.columns to fetch filed name , value and data type.
so result would be like
Column_Name Value datatype
------------- ------- --------------
stock_code A112 varchar
automatic 1 bit
semiautomatic 0 bit
manual 1 bit
this type of output can we have just joining my sql with information_schema.columns. if possible then please provide me the right sql which will give me the above sort of output.
thanks
please guide. thanks
You could use case for that:
select case bit_field when 1 then 'yes' else 'no' end as ColumnAlias
...
Create a lookup table for Boolean values.
CREATE TABLE dbo.Boolean
(
Id bit PRIMARY KEY
, YesNo varchar(3) UNIQUE
, TrueFalse varchar(10)
)
INSERT INTO dbo.Boolean VALUES (0, 'No', 'False')
INSERT INTO dbo.Boolean VALUES (1, 'Yes', 'True')
Then join to the Boolean table for each bit column.
SELECT v.stock_code, v.makeid, v.modelid, v.enginesize
, a.YesNo automatic, s.YesNo semiautomatic, m.YesNo manual
FROM dbo.VehicleInfoForParts v
LEFT OUTER JOIN dbo.Boolean a ON a.Id = v.automatic
LEFT OUTER JOIN dbo.Boolean s ON s.Id = v.semiautomatic
LEFT OUTER JOIN dbo.Boolean m ON m.Id = v.manual
I recommend doing this in your application, not in the database. When you load your data from SQL Server into, say, an object in your application, handle this in the ToString method of the field you use for your database bit column (assuming you use .NET, if not, use something similar).
You can use the implicit conversion:
select stock_code,makeid,modelid,enginesize,
CASE WHEN automatic = 1 THEN 'Yes' ELSE 'No' END as automatic,
CASE WHEN semiautomatic = 1 THEN 'Yes' ELSE 'No' END as semiautomatic,
CASE WHEN manual = 1 THEN 'Yes' ELSE 'No' END as manual
from VehicleInfoForParts