Set Date as a min date per ID with update - sql

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.

Related

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

Issue with case null in 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.

Changing when to if statement in SQL server

How do I change the following code to an if statement that returns a boolean 0 or 1 value? My end results I would like to have, is one column listing the interest rate of 2, and my results column with a 0 or 1 if the condition is true.
(Case when new_interestratevariability = 2
and (new_interestrateindex = 1 or new_interestrateindex = 2 or new_interestrateindex = 3 or new_interestrateindex = 4 or new_interestrateindex = 6)
and new_crms_dt = #Curr_Date
then 0 else 1 end) as CIEDIT_VAL_96,
Currently, I am getting something like below:
Results Table
To filter rows, use a Where clause. The Case statement in the Select clause will modify the value shown on the row.
Select *
from table
Where new_interestratevariability = 2
and new_interestrateindex IN (1,2,3,4,6)
and new_crms_dt = #Curr_Date
Found my answer, it was as simple as adding "not in" instead of just "in". Thanks everyone
(Case when new_interestratevariability = 2
and (new_interestrateindex not in(1,2,3,4,6))
and new_crms_dt = #Curr_Date
then 1 else 0 end) as CIEDIT_VAL_96,

Oracle SQL CASE expression in WHERE clause only when conditions are met

Cant quite figure this one out, i have a set of conditions that i want to be met only if a value is in a field.
So if the Status is complete i want to have three where clause's, if the status doesn't equal complete then i don't want any where clause.
Code
SELECT *
FROM mytable
WHERE CASE WHEN Status = 'Complete'
THEN (included = 0 OR excluded = 0 OR number IS NOT NULL)
ELSE *Do nothing*
It is usually simple to only use boolean expressions in the WHERE. So:
WHERE (Status <> 'Complete') OR
(included = 0 OR excluded = 0 OR number IS NOT NULL)
If Status could be NULL:
WHERE (Status <> 'Complete' OR Status IS NULL) OR
(included = 0 OR excluded = 0 OR number IS NOT NULL)
You can translate the natural language in SQL, then, if possible, reformulate.
SELECT *
FROM mytable
WHERE (Status = 'Complete' and (included = 0 OR excluded = 0 OR number IS NOT NULL))
or status <> 'Complete'
or status IS NULL;
It doesn't look like you really need a CASE statement, just use it like this:
SELECT *
FROM mytable
WHERE where (Status = 'Complete' and (included = 0 OR excluded = 0 OR number IS NOT NULL)) or (*Your do nothing*)

Using CASE within a where clause - with a parameter

I am looking for a good example of a case statement inside a where clause, using a variable. The number returned by the variable determines the result of the where clause. My query looks like this:
IF #RequestType = 99
SELECT #Received = count(*)
FROM Request r
WHERE request_received_date between #beginDate and #endDate
AND request_type_id <> 5
ELSE IF #RequestType = 100
BEGIN
SELECT #Received = count(*)
FROM Request r
WHERE request_received_date between #beginDate and #endDate
END
ELSE
BEGIN
SELECT #Received = count(*)
FROM Request r
WHERE request_received_date between #beginDate and #endDate
AND request_type_id =
(CASE WHEN #RequestType = 1 THEN (1)
WHEN #RequestType = 2 THEN (2)
WHEN #RequestType = 3 THEN (3)
WHEN #RequestType = 4 THEN (4)
WHEN #RequestType = 5 THEN (5)
END)
END
So as you can see, there are 7 options - the customer wants to be flexible with the amount of data they see in the report. This looks cumbersome to me but I can't think of any other way to do this.
you could probably simplify the query to...
SELECT
count(*) as Received
FROM
( select 3 as RqType,
'2015-10-01' as beginDate,
'2015-10-20' as endDate) as PV,
Request r
WHERE
request_received_date between PV.beginDate and PV.endDate
AND case when PV.RqType = 100 then 1=1
when PV.RqType = 99 then r.request_type_id <> 5
when PV.RqType <= 6 then PV.RqType = r.request_type_id
end
The LAST case/when component matches on the request type is getting the values under 6 to match that of the request type. If you have negatives, then just adjust that accordingly.
I revised the query to have a prequery "PV" indicating the parameter values you are looking for, so they can just be changed to whatever request type and date-range as you need. This should be good for SQL-Server, and probably other SQL engines too. By just doing a query of hard values with no "FROM", it essentially creates a result set of a single record with those values of which you can then use for the rest of the query. Any by being a single record, no issue for any Cartesian joins.
There is usually no need for CASE WHEN in WHERE clauses, as you have AND and OR. Your queries translate to:
select #Received = count(*)
from request
where request_received_date between #beginDate and #endDate
and
(
#RequestType = 100
or
(#RequestType = 99 and request_type_id <> 5)
or
(#RequestType = request_type_id and request_type_id in (1,2,3,4,5))
);