Multiple Case Conditions - sql

I am using the following query to get the credit points, how will I add two more conditions if the ID_Points =2 then 0.5 and ID_points = 3 then 0.25
SELECT
Attend_ID,
Attend_Date,
ID_Points,
Employee_ID,
First_Name,
Last_Name,
NextDate,
NEXT123,
Difference,
DAY90CREDIT,
CREDITDATE,
CASE
WHEN (day90Credit = 0 AND CreditDate < Getdate())
OR DateAdd(DAY, 90, attend_date) < COALESCE (NextDate, GETDATE())
AND ID_Points = 1 THEN 1
ELSE 0 END AS TOTALCREDIT
FROM
dbo.Test_DiffNintyDays

Good formatting makes this a lot easier and more obvious:
Assuming your description was literal:
SELECT Attend_ID,
Attend_Date,
ID_Points,
Employee_ID,
First_Name,
Last_Name,
NextDate,
NEXT123,
Difference,
DAY90CREDIT,
CREDITDATE,
CASE
WHEN (day90Credit = 0 AND CreditDate < Getdate())
OR DateAdd(DAY, 90, attend_date) < COALESCE (NextDate, GETDATE())
AND ID_Points = 1 THEN 1
WHEN ID_Points = 2 THEN 0.5
WHEN ID_Points = 3 THEN 0.25
ELSE 0 END AS TOTALCREDIT
FROM dbo.Test_DiffNintyDays
However, I suspect you really meant this:
SELECT Attend_ID,
Attend_Date,
ID_Points,
Employee_ID,
First_Name,
Last_Name,
NextDate,
NEXT123,
Difference,
DAY90CREDIT,
CREDITDATE,
CASE
WHEN (day90Credit = 0 AND CreditDate < Getdate())
OR DateAdd(DAY, 90, attend_date) < COALESCE (NextDate, GETDATE())
AND ID_Points = 1 THEN 1
WHEN (day90Credit = 0 AND CreditDate < Getdate())
OR DateAdd(DAY, 90, attend_date) < COALESCE (NextDate, GETDATE())
AND ID_Points = 2 THEN 0.5
WHEN (day90Credit = 0 AND CreditDate < Getdate())
OR DateAdd(DAY, 90, attend_date) < COALESCE (NextDate, GETDATE())
AND ID_Points = 3 THEN 0.25
ELSE 0 END AS TOTALCREDIT
FROM dbo.Test_DiffNintyDays

Related

Have non-boolean result in Case When Function

I am trying to create a query that will break results into separate columns. The best formula that I can find is the Case When function, but it says the Then part of the equation must be Boolean (or a true/false result). Is there a way for the Then to calculate a number 3-1 for example?
Case
when
DATEDIFF(day, T0.[DocDueDate], getdate()) > 0
AND DATEDIFF(day, T0.[DocDueDate], getdate()) < 30
then
(T0.[DocTotal] - T0.[PaidToDate])
else
' '
end
as "Greater than 1",
Case
when
DATEDIFF(day, T0.[DocDueDate], getdate()) > 30
AND DATEDIFF(day, T0.[DocDueDate], getdate()) < 60
then
(T0.[DocTotal] - T0.[PaidToDate])
else
' '
end
as "Greater than 30"
You have a problem with type compatibility. I would recommend that you simply use NULL for no match:
(case when DATEDIFF(day, T0.[DocDueDate], getdate()) > 0 AND DATEDIFF(day, T0.[DocDueDate], getdate()) < 30
then (T0.[DocTotal] - T0.[PaidToDate])
end) as Greater_than_1,
(case when DATEDIFF(day, T0.[DocDueDate], getdate()) > 30 and DATEDIFF(day, T0.[DocDueDate], getdate()) < 60
then (T0.[DocTotal] - T0.[PaidToDate])
end) as Greater_than_30
I would also guess that you intend <= 30 for the first condition.
If you use sql server then your code snip will be like below.
you have to keep same data type on after then and else as you used string type after using else so you have to convert it on later then
Case
when
DATEDIFF(day, T0.[DocDueDate], getdate()) > 0
AND DATEDIFF(day, T0.[DocDueDate], getdate()) < 30
then
( convert(varchar(255), T0.[DocTotal] - T0.[PaidToDate]))
else
' '
end
as Greater_than_1,
Case
when
DATEDIFF(day, T0.[DocDueDate], getdate()) > 30
AND DATEDIFF(day, T0.[DocDueDate], getdate()) < 60
then
(convert(varchar(255), T0.[DocTotal] - T0.[PaidToDate]))
else
' '
end
as Greater_than_30
Found that i needed to cast the equation as an integer as below.
Case when
DATEDIFF(day, T0.[DocDueDate], getdate()) > 0
AND DATEDIFF(day, T0.[DocDueDate], getdate()) <30
then
cast( (T0.[DocTotal]-T0.[PaidToDate]) as varchar(12) )
else
' '
end as "Greater than 1"
Here is how you can do this with a variety of methods. TSET is just generating dates from June 1 to today for the test.
WITH tset(td)
AS (
SELECT CAST('2018-08-01' AS DATE) AS td
UNION ALL
SELECT DATEADD(d, -1, td)
FROM tset
WHERE td > CAST('2018-06-01' AS DATE))
-- Actual examples start here
SELECT td
-- Diff is just showing the difference in days so you can see the group assignements
, DATEDIFF(d, td, GETDATE()) AS diff
-- This column groups into < 30, 31-60, and > 60
, CASE
WHEN DATEDIFF(d, td, GETDATE()) < 30 THEN 1 ELSE CASE
WHEN DATEDIFF(d, td, GETDATE()) < 60 THEN 2 ELSE 3
END
END three_sets
-- this example will group into any number of 30 day sets.
, cast ( DATEDIFF(d, td, GETDATE()) as int) / 30 any_number_of_sets
FROM tset
ORDER BY td;
Some sample Results:
td diff three_sets any_number_of_sets
2018-06-01 66 3 2
2018-06-02 65 3 2
2018-06-03 64 3 2
. . .
2018-06-12 55 2 1
2018-06-13 54 2 1
2018-06-14 53 2 1
. . .
2018-07-09 28 1 0
2018-07-10 27 1 0
2018-07-11 26 1 0

Selecting multiple subqueries

I have subqueries that need to return different results. Each subqueries used different aggregate functions like SUM() AND COUNT(*). What I did is I encapsulate them with SELECT (SELECT subquery, SELECT subquery) not sure if this possible.
Expected result:
TwoYears
123
5
SELECT(
(SELECT
(SELECT SUM(AHT)
FROM
(
SELECT
CASE
WHEN DATEDIFF(year, [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[HireDate], GETDATE()) >= 2 AND (DATEDIFF(year, [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[HireDate], GETDATE())) <= 2 OR (DATEDIFF(year, [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[HireDate], GETDATE())) <= 1
THEN [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[Value]
END AS AHT
FROM [AgentProfile_CRT].[dbo].[uvw_AHTMaster] WHERE [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[Month] = 'January' AND [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[Year] = 2018 AND [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[AccountID] = 8 AND [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[LOBID] = 23
) f
WHERE AHT = AHT ) AS TwoYears),
(SELECT
(SELECT COUNT(*) AS TwoYears
FROM
(
SELECT
CASE
WHEN DATEDIFF(year, [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[HireDate], GETDATE()) >= 2 AND (DATEDIFF(year, [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[HireDate], GETDATE())) <= 2 OR (DATEDIFF(year, [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[HireDate], GETDATE())) <= 1
THEN 'Good'
END AS Result
FROM [AgentProfile_CRT].[dbo].[uvw_AHTMaster] WHERE [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[Month] = 'January' AND [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[Year] = 2018 AND [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[AccountID] = 8 AND [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[LOBID] = 23
) f
WHERE Result = 'Good') AS TwoYears)
) a
You need to make a union all and remove some of your subselects.
Like this:
SELECT SUM(AHT) as TwoYears
FROM (
SELECT CASE
WHEN DATEDIFF(year, [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[HireDate], GETDATE()) >= 2
AND (DATEDIFF(year, [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[HireDate], GETDATE())) <= 2
OR (DATEDIFF(year, [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[HireDate], GETDATE())) <= 1
THEN [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[Value]
END AS AHT
FROM [AgentProfile_CRT].[dbo].[uvw_AHTMaster]
WHERE [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[Month] = 'January'
AND [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[Year] = 2018
AND [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[AccountID] = 8
AND [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[LOBID] = 23
) f
WHERE AHT = AHT
union all
SELECT COUNT(*) AS TwoYears
FROM (
SELECT CASE
WHEN DATEDIFF(year, [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[HireDate], GETDATE()) >= 2
AND (DATEDIFF(year, [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[HireDate], GETDATE())) <= 2
OR (DATEDIFF(year, [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[HireDate], GETDATE())) <= 1
THEN 'Good'
END AS Result
FROM [AgentProfile_CRT].[dbo].[uvw_AHTMaster]
WHERE [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[Month] = 'January'
AND [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[Year] = 2018
AND [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[AccountID] = 8
AND [AgentProfile_CRT].[dbo].[uvw_AHTMaster].[LOBID] = 23
) f
WHERE Result = 'Good'

How do I correctly perform CASE logic?

I want to create a "calculated" column base on "if...else" logic.
I've tried:
x.ApplicationID
,CASE WHEN DATEDIFF(dd, x.CreateDate, GETDATE()) < 7 THEN 1
WHEN DATEDIFF(dd, x.CreateDate, GETDATE()) < 14 THEN 2
WHEN DATEDIFF(dd, x.CreateDate, GETDATE()) < 30 THEN 3
ELSE 0
END AS Prodleni
which raises an error:
Incorrect syntax near the keyword 'WHEN'.
Help would be appreciated.
Only 1 else is needed. you need to use like below-
x.ApplicationID
,CASE WHEN DATEDIFF(dd, x.CreateDate, GETDATE()) < 7 THEN 1
WHEN DATEDIFF(dd, x.CreateDate, GETDATE()) < 14 THEN 2
WHEN DATEDIFF(dd, x.CreateDate, GETDATE()) < 30 THEN 3
ELSE 0
END AS Prodleni
read more from
https://learn.microsoft.com/en-us/sql/t-sql/language-elements/case-transact-sql

Using a sub query in column list

I would like to create a query that would count how many records were created in the last 7, 14 and 28 days. My result would return something like:
7Days 14Days 28Days
21 35 56
I know how to for each timepsan e.g. 7 days, but I do I capture all three in one query?
select count(*) from Mytable
where Created > DATEADD(day,-8, getdate())
Also not pretty, but doesn't rely on subqueries (table/column names are from AdventureWorks). The case statement returns 1 if it falls within your criteria, 0 otherwise - then you just sum the results :
select sum(case when datediff(day, modifieddate, getdate()) <= 7
then 1 else 0 end) as '7days',
sum(case when datediff(day, modifieddate, getdate()) > 7
and datediff(day, modifieddate, getdate()) <= 14
then 1 else 0 end) as '14days',
sum(case when datediff(day, modifieddate, getdate()) > 14
and datediff(day, modifieddate, getdate()) <= 28
then 1 else 0 end) as '28days'
from sales.salesorderdetail
Edit: Updated the datediff function - the way it was written, it would return a negative number (assuming modifieddate was in the past) causing all items to fall under the first case. Thanks to Andriy M for pointing that out
It isn't the prettiest code in the world, but it does the trick. Try selecting from three subqueries, one for each range.
select * from
(select COUNT(*) as Cnt from Log_UrlRewrites where CreateDate >= DATEADD(day, -7, getdate())) as Seven
inner join (select COUNT(*) as Cnt from Log_UrlRewrites where CreateDate >= DATEADD(day, -14, getdate())) as fourteen on 1 = 1
inner join (select COUNT(*) as Cnt from Log_UrlRewrites where CreateDate >= DATEADD(day, -28, getdate())) as twentyeight on 1 = 1
select
(
select count(*)
from Mytable
where Created > DATEADD(day,-8, getdate())
) as [7Days],
(
select count(*)
from Mytable
where Created > DATEADD(day,-15, getdate())
) as [14Days],
(
select count(*)
from Mytable
where Created > DATEADD(day,-29, getdate())
) as [28Days]
SELECT
[7Days] = COUNT(CASE UtmostRange WHEN 7 THEN 1 END),
[14Days] = COUNT(CASE UtmostRange WHEN 14 THEN 1 END),
[28Days] = COUNT(CASE UtmostRange WHEN 28 THEN 1 END)
FROM (
SELECT
*,
UtmostRange = CASE
WHEN Created > DATEADD(day, -8, GETDATE()) THEN 7
WHEN Created > DATEADD(day, -15, GETDATE()) THEN 14
WHEN Created > DATEADD(day, -29, GETDATE()) THEN 28
END
FROM Mytable
) s

SQL Grouping and DATEDIFF Issue

The query below is using Axosoft's OnTime DB with a few custom fields. If you ignore the custom fields and have some sample data this should work.
What I'm trying to do:
Return a query that has a count(total) number of open tickets that have been open during these time frames:
Less than a day
1 Day
2 Days
3 Days
4 Days
5 Days
6 Days
More than a week
this is for a ticket aging query. Here's the query below:
DECLARE #endDate DateTime;
SET #endDate = '03/18/2011';
WITH
WorkItems AS
(
SELECT
i.ProjectID AS ProjectID,
CASE WHEN ic.Custom_279 = 'Bug' THEN 'Issue' WHEN ic.Custom_279 IS NULL THEN 'Other' WHEN LTRIM(RTRIM(ic.Custom_279)) = '' THEN 'Other' ELSE ic.Custom_279 END AS WorkItemType,
i.IncidentNumber AS ID,
i.Name AS Name,
--CASE WHEN ic.Custom_264 < '1901-01-01' THEN NULL ELSE ic.Custom_264 END AS DateReported,
CASE WHEN i.CreatedDateTime < '1901-01-01' THEN NULL ELSE i.CreatedDateTime END AS DateReported,
CASE WHEN ic.Custom_265 < '1901-01-01' THEN NULL ELSE ic.Custom_265 END AS DateResolutionBegan,
CASE WHEN ic.Custom_266 < '1901-01-01' THEN NULL ELSE ic.Custom_266 END AS DateSignoffRequested,
CASE WHEN ic.Custom_267 < '1901-01-01' THEN NULL ELSE ic.Custom_267 END AS DateClosed
FROM
dbo.Incidents AS i
INNER JOIN dbo.IncidentCustomFields AS ic ON ic.IncidentID = i.IncidentID
WHERE
i.Archived = 0
),
ProjectDescendantsIncludingSelf AS
(
SELECT
p.ProjectID AS ProjectID,
p.ProjectID AS DescendantProjectID,
CAST('/' + p.Name AS NVARCHAR) AS ProjectPath
FROM
dbo.Projects AS p
UNION ALL
SELECT
pd.ProjectID AS ProjectID,
p.ProjectID AS DescendantProjectID,
CAST(pd.ProjectPath + N'/' + p.Name AS NVARCHAR) AS ProjectPath
FROM
ProjectDescendantsIncludingSelf AS pd
INNER JOIN dbo.Projects AS p ON p.ParentID = pd.DescendantProjectID
),
OpenTicketsLessThanDay AS
(SELECT
COUNT(ID) AS [LessThanDayTicketCount],
CASE WHEN DATEDIFF(DAY, DateReported, #endDate) < 1 THEN DATEDIFF(DAY, DateReported, #endDate) ELSE NULL END AS [LessThanDay],
--CASE WHEN (DATEDIFF(DAY, DateReported, #endDate) > 1) AND (DATEDIFF(DAY, DateReported, #endDate) <= 2) THEN DATEDIFF(DAY, DateReported, #endDate) ELSE NULL END AS [GreaterThan1Day],
--CASE WHEN (DATEDIFF(DAY, DateReported, #endDate) > 2) AND (DATEDIFF(DAY, DateReported, #endDate) <= 3) THEN DATEDIFF(DAY, DateReported, #endDate) ELSE NULL END AS [GreaterThan2Days],
--CASE WHEN (DATEDIFF(DAY, DateReported, #endDate) > 3) AND (DATEDIFF(DAY, DateReported, #endDate) <= 4) THEN DATEDIFF(DAY, DateReported, #endDate) ELSE NULL END AS [GreaterThan3Days],
--CASE WHEN (DATEDIFF(DAY, DateReported, #endDate) > 4) AND (DATEDIFF(DAY, DateReported, #endDate) <= 5) THEN DATEDIFF(DAY, DateReported, #endDate) ELSE NULL END AS [GreaterThan4Days],
--CASE WHEN (DATEDIFF(DAY, DateReported, #endDate) > 5) AND (DATEDIFF(DAY, DateReported, #endDate) <= 6) THEN DATEDIFF(DAY, DateReported, #endDate) ELSE NULL END AS [GreaterThan5Days],
--CASE WHEN (DATEDIFF(DAY, DateReported, #endDate) > 6) AND (DATEDIFF(DAY, DateReported, #endDate) <= 7) THEN DATEDIFF(DAY, DateReported, #endDate) ELSE NULL END AS [GreaterThan6Days],
--CASE WHEN DATEDIFF(WEEK, DateReported, #endDate) > 1 THEN DATEDIFF(DAY, DateReported, #endDate) ELSE NULL END AS [GreaterThanWeek],
--DateReported,
--DateClosed,
--d.ProjectPath
FROM WorkItems wi
INNER JOIN ProjectDescendantsIncludingSelf d ON d.DescendantProjectID = wi.ProjectID
WHERE
DateReported < #endDate AND
(DateClosed IS NULL OR DateClosed > #endDate) AND
d.ProjectID = 182 AND
d.DescendantProjectID != 185
GROUP BY LessThanDay
)
SELECT [LessThanDayTicketCount] FROM OpenTicketsLessThanDay
GROUP BY LessThanDay
ORDER BY LessThanDay ASC
I presume you need something like one or the other of these.
DECLARE #EndDate datetime = getdate()
SELECT
COUNT(CASE WHEN modify_date > DATEADD(DAY,-1,#EndDate) THEN 1 END) AS [LessThanDay],
COUNT(CASE WHEN modify_date > DATEADD(DAY,-2,#EndDate) AND modify_date <= DATEADD(DAY,-1,#EndDate) THEN 1 END) AS [GreaterThan1Day],
COUNT(CASE WHEN modify_date > DATEADD(DAY,-3,#EndDate) AND modify_date <= DATEADD(DAY,-2,#EndDate) THEN 1 END) AS [GreaterThan2Days],
COUNT(CASE WHEN modify_date > DATEADD(DAY,-4,#EndDate) AND modify_date <= DATEADD(DAY,-3,#EndDate) THEN 1 END) AS [GreaterThan3Days],
COUNT(CASE WHEN modify_date > DATEADD(DAY,-5,#EndDate) AND modify_date <= DATEADD(DAY,-4,#EndDate) THEN 1 END) AS [GreaterThan4Days],
COUNT(CASE WHEN modify_date > DATEADD(DAY,-6,#EndDate) AND modify_date <= DATEADD(DAY,-5,#EndDate) THEN 1 END) AS [GreaterThan5Days],
COUNT(CASE WHEN modify_date > DATEADD(DAY,-7,#EndDate) AND modify_date <= DATEADD(DAY,-6,#EndDate) THEN 1 END) AS [GreaterThan6Days],
COUNT(CASE WHEN modify_date <= DATEADD(DAY,-7,#EndDate) THEN 1 END) AS [GreaterThanWeek]
FROM sys.objects
WHERE modify_date <= #EndDate
SELECT
COUNT(CASE WHEN DATEDIFF(DAY, modify_date, #EndDate) = 0 THEN 1 END) AS [LessThanDay],
COUNT(CASE WHEN DATEDIFF(DAY, modify_date, #EndDate) = 1 THEN 1 END) AS [GreaterThan1Day],
COUNT(CASE WHEN DATEDIFF(DAY, modify_date, #EndDate) = 2 THEN 1 END) AS [GreaterThan2Days],
COUNT(CASE WHEN DATEDIFF(DAY, modify_date, #EndDate) = 3 THEN 1 END) AS [GreaterThan3Days],
COUNT(CASE WHEN DATEDIFF(DAY, modify_date, #EndDate) = 4 THEN 1 END) AS [GreaterThan4Days],
COUNT(CASE WHEN DATEDIFF(DAY, modify_date, #EndDate) = 5 THEN 1 END) AS [GreaterThan5Days],
COUNT(CASE WHEN DATEDIFF(DAY, modify_date, #EndDate) = 6 THEN 1 END) AS [GreaterThan6Days],
COUNT(CASE WHEN DATEDIFF(DAY, modify_date, #EndDate) > 6 THEN 1 END) AS [GreaterThanWeek]
FROM sys.objects
WHERE modify_date <= #EndDate