Issue with case null in sql - sql

SELECT Id
FROM dbo.OWL_AddlDataFields
WHERE CustomerId = #BaseCustomerId
AND AddlDataFieldCategoryId = #AddlDataFieldCategoryId
AND AddlDataFieldGroupId = CASE
WHEN #AddlDataFieldGroupId = 0 THEN NULL
ELSE #AddlDataFieldGroupId
END
AND Name = #DataFieldName
The above query does not returns any result. I think above query has issue with the 'AddlDataFieldCategoryId =' and the null from the case. Can anybody correct the query?

The issue with your CASE expression is that you are comparing a column to a predicate which might be NULL using the equals operator. This won't behave as expected, because NULL comparisons should use IS NULL instead of equals. One possible workaround would be to coalesce AddlDataFieldGroupId to a numeric value. Then, we can be certain that the CASE expression would only be comparing one number to another.
WHERE ... AND
COALESCE(AddlDataFieldGroupId, 0) = CASE WHEN
#AddlDataFieldGroupId = 0
THEN 0 ELSE #AddlDataFieldGroupId END

If your AddlDataFieldGroupId cannot be zero, then you don't need the CASE at all. This will do the job:
SELECT Id
FROM dbo.OWL_AddlDataFields
WHERE CustomerId = #BaseCustomerId
AND AddlDataFieldCategoryId = #AddlDataFieldCategoryId
AND AddlDataFieldGroupId = #AddlDataFieldGroupId
AND Name = #DataFieldName
If AddlDataFieldGroupId can be zero, but cannot be negative, you can do this:
SELECT Id
FROM dbo.OWL_AddlDataFields
WHERE CustomerId = #BaseCustomerId
AND AddlDataFieldCategoryId = #AddlDataFieldCategoryId
AND AddlDataFieldGroupId = CASE WHEN
#AddlDataFieldGroupId = 0 THEN -1 ELSE #AddlDataFieldGroupId END
AND Name = #DataFieldName
Alternatively, this will work regardless of what AddlDataFieldGroupId can be:
SELECT Id
FROM dbo.OWL_AddlDataFields
WHERE CustomerId = #BaseCustomerId
AND AddlDataFieldCategoryId = #AddlDataFieldCategoryId
AND AddlDataFieldGroupId = CASE WHEN
#AddlDataFieldGroupId = 0 THEN AddlDataFieldGroupId - 1 ELSE #AddlDataFieldGroupId END
AND Name = #DataFieldName
Note: all these solutions assume that AddlDataFieldGroupId cannot be NULL.

Related

Set Date as a min date per ID with update

I'm trying to set resolved date as a first date per user(ELSE CASE WHEN part of a code),
I need to make it in CASE statement, but MIN() function will just find minimum value in whole column, is there any way to do something like this in a code below?
UPDATE [ER].[dbo].[B]
SET [Created] = A.Created,
[Updated] = A.updated,
[Resolved] = CASE WHEN (A.statusID <> 3 and B.StatusID = 3)
THEN NULL
ELSE CASE WHEN (A.statusID = 3 and B.StatusID = 3 and (A.resolutiondate > B.Resolved)) THEN MIN(A.resolutiondate)
ELSE B.Resolved
END
END,
[StatusID] = A.StatusID,
[Status] = A.StatusName,
[Priority] = A.PriorityName,
[Assignee] = A.Assignee,
[Resolution] = A.resolution
FROM A
WHERE CONVERT(nvarchar,A.ID) = [ER].[dbo].[B].ExternalId and (B.Resolved IS NOT NULL)
You want to use OVER PARITION BY to get the min per subgroup / user. You can find details on this function here.

where clause work only when case is satisfied

I have made a view that has a where clause :
WHERE M.Deleted = 0 AND I.Deleted = 0 AND L.Deleted = 0
is there a possible way to make L.Deleted = 0 only work on a specific case? My plan is when the M.TYPE_ID != 4 then add this L.Delete = 0 to where clause, and without it otherwise
I tried to make something like:
AND CASE WHEN M.TYPE_ID != 4 THEN L.DELETED = 0 ELSE --(i want here to make this entire part of where clause to be invalid if the case is not valid)
or there are other ways to do that like intersect the same select above but without that condition ?
any help would be appreciated, thanks.
Yes, you can do:
WHERE M.Deleted = 0 AND I.Deleted = 0 AND
(M.TYPE_ID = 4 OR L.Deleted = 0)
You don't need a case expression.
You might find the logic simpler to follow as:
WHERE M.Deleted = 0 AND I.Deleted = 0 AND
( NOT (M.TYPE_ID <> 4 AND L.Deleted <> 0) )
The simplest way would be to include the valid condition in two checks and or them together.
e.g.
Select * from x where (x.isvalid = 1 and x.deleted = 0) or (x.isvalid <> 1 and x.othercheck = 1)

SQL Select rows based on parameters

so I created a customer table that looks a bit like this
Each customer is either new, recurring, or reactivated, and each customer can only be one type so whatever type it is has a 1 in that field and a 0 in all other fields.
I am created a report where I want to have a parameter called customer type that lets you select new, recurring, reactivated, and all, and it will show you only the customer type that you select.
I am not sure how to do this.
I have the whole query done, I just need some help with the where clause.
The psuedo code would be something like this
Case when #CustomerType = 'NEW'
THEN where cs.brandnewcustomer = 1
Case when #CustomerType = 'RECURRING'
THEN where cs.recurringcustomer= 1
Case when #CustomerType = 'REACTIVATED'
THEN where cs.reactivatedcustomer= 1
else case when #CustomerType = 'All' end
Does anyone have any tips on how to turn this into actual code?
You can form your conditions as:
WHERE (cs.brandnewcustomer = 1 AND #CustomerType = 'NEW')
OR
(cs.recurringcustomer = 1 AND #CustomerType = 'RECURRING')
OR
(cs.reactivatedcustome = 1 AND #CustomerType = 'REACTIVATED')
OR
(#CustomerType = 'ALL')
It would need to be structured like this:
SELECT ... FROM ...
WHERE cs.brandnewcustomer = CASE WHEN #CustomerType = 'NEW' THEN 1 ELSE 0 END
AND cs.recurringcustomer = CASE WHEN #CustomerType = 'RECURRING' THEN 1 ELSE 0 END
AND cs.reactivatedcustomer = CASE WHEN #CustomerType = 'REACTIVATED' THEN 1 ELSE 0 END
OR 1 = CASE WHEN #CustomerType = 'All' THEN 1 ELSE 0 END
Put this CASE statement in the WHERE clause:
select * from customers
where 1 = case #CustomerType
when 'NEW' then brandnewcustomer
when 'RECURRING' then recurringcustomer
when 'REACTIVATED' then reactivatedcustomer
when 'All' then 1
end
In case the parameter does not match any of the 4 values then nothing will be returned.
See the demo.
I think this needs to be normalized
Customer types needs to be in a table with a primary key tb_CustomerType
enter image description here
Customer table needs to have a foreign key to the customer type tb_Customer
enter image description here
you do not have to have a case statement if you have this kind of a table structure

Not able to query with null values

I need to query based on the parameter, used parameter in the CASE clause.
Parameter will contain these values : contactSuccess,contactFail,notcontacted
We have column : empCommunication which is boolean. It will take 0,1, null
Based on the Parameter value, I need to run the query.
Eg: if Parameter is contactSuccess then Where clause should be
empCommunication = 1
if Parameter is contactFail then Where clause should be
empCommunication = 0
The above two scenario's are working with the below query, but if fails with
Parameter is notContacted, in this case Where clause should be
empCommunication IS NULL.
Kindly help me on this.
SELECT
empCategory as name,
count(*) as value
from EmployeeRecords R
WHERE empCommunication =
CASE ?
WHEN 'contactSuccess' THEN 1
WHEN 'contactFail' THEN 0
WHEN 'notcontacted' THEN IS NULL
END
group by empCategory
Use coalesce() to cover the case where the parameter is 'notcontacted' with a different value like -1:
SELECT
empCategory as name,
count(*) as value
from EmployeeRecords R
WHERE coalesce(empCommunication, -1) =
CASE ?
WHEN 'contactSuccess' THEN 1
WHEN 'contactFail' THEN 0
WHEN 'notcontacted' THEN -1
END
group by empCategory
Assume that your param is p_param, you could change your query to
SELECT
empCategory AS name,
COUNT(*) AS value
FROM EmployeeRecords
WHERE
(empCommunication IS NULL AND p_param = 'notcontacted')
OR (empCommunication = 1 AND p_param = 'contactSuccess')
OR (empCommunication = 0 AND p_param = 'contactFail')
GROUP BY empCategory;
Try this one!
SELECT
empCategory as name,
count(*) as value
from EmployeeRecords R WHERE empCommunication =
(CASE a_column_in_table
WHEN 'contactSuccess' THEN 1
WHEN 'contactFail' THEN 0
WHEN 'notcontacted' THEN NULL
else null
END)
group by empCategory;`

How to filter Even and Odd numbers and move/copy them to an empty column?

i have a simple problem. i have a column with numbers. i need to filter them to even and odd numbers, but if a number is even than i need to copy or move it to "even-number-column" in the same table. if the number is odd then move it to "odd-number-column" in the same table.
this is my code:
select distinct all_numbers, even-number-column, odd-number-column
case when all_numbers%2=0
then UPDATE my_table SET even-number-column = all_numbers
else UPDATE my_table SET odd-number-column = all_numbers
end
from my_table ;
If you want a SELECT:
select
distinct all_numbers,
CASE
WHEN when all_numbers%2 = 0 THEN all_numbers
ELSE 0 -- or NULL
END as even-number-column,
CASE
WHEN when all_numbers%2 = 1 THEN all_numbers
ELSE 0 -- or NULL
END as odd-number-column
from my_table ;`
If you want an update
UPDATE my_table
SET
even-number-column = CASE
WHEN when all_numbers%2 = 0 THEN all_numbers
ELSE even-number-column -- or change for 0 or NULL
END,
odd-number-column = CASE
WHEN when all_numbers%2 = 1 THEN all_numbers
ELSE odd-number-column -- or change for 0 or NULL
END
Use an array to make it simple
update t
set
odd = (array[null, all_numbers])[all_numbers % 2 + 1],
even = (array[all_numbers, null])[all_numbers % 2 + 1]