Have non-boolean result in Case When Function - sql

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

Related

T-SQL pivot inventory aging by day range

Writing a T-SQL statement to display items in inventory broken out by day range (pivot).
For example from this inventory table:
ItemName
DateCreated
PO_ID
A
2020-10-07
0
B
2020-10-07
1
A
2020-10-22
2
A
2020-10-22
2
A
2020-10-22
2
B
2020-10-29
3
Would like to generate the bellow results (typically a pivot table), showing the number of pieces per ItemName per day range. The date used to calculate the # of days since DateCreated would be the day the report was ran or passed in as a parameter - in the example shown here, the date used is from '2020-11-07':
ItemName
0-10 days
11-20 days
21-30 days
>30 days
A
0
3
0
1
B
1
0
0
1
Not sure what would be the best way to write the statement to generate the above results?
I would use conditional aggregation:
select itemName,
sum(case when datediff(day, dateCreated, getdate()) <= 10 then 1 else 0 end) as days_0_10,
sum(case when datediff(day, dateCreated, getdate()) > 10 and
datediff(day, dateCreated, getdate()) <= 20
then 1 else 0 end) as days_11_20,
sum(case when datediff(day, dateCreated, getdate()) > 20 and
datediff(day, dateCreated, getdate()) <= 30
then 1 else 0 end) as days_21_30,
sum(case when datediff(day, dateCreated, getdate()) > 30 then 1 else 0 end) as days_31
from t
group by itemName
I would use something similar to the following query SQL Server:
SELECT *
FROM
(
SELECT [ItemName],[PO_ID],
CASE
WHEN DATEDIFF(day, DateCreated, getdate()) BETWEEN 0 AND 10 THEN '0-10 days'
WHEN DATEDIFF(day, DateCreated, getdate()) BETWEEN 11 AND 20 THEN '11-20 days'
WHEN DATEDIFF(day, DateCreated, getdate()) BETWEEN 21 AND 30 THEN '21-30 days'
ELSE '>30 days'
END AS PeriodCreated
FROM [TableName])
) src
pivot
(
COUNT(PO_ID)
FOR PeriodCreated in ([0-10 days], [11-20 days], [>30 days])
) piv

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

Display data in Days range

I have a sql query output as below
Customer LastModifiedDate
A 1/12/2013
B 1/1/2015
C 1/28/2015
Now I need to display the customers count whose details updated in different days range like (30-60 days), (61-90 Days) and 90+(More than 90 days)
For example please see the output below
DaysRange CustomersCount
30-60 1
61-90 1
90+ 1
Please help me in achieving the above output
Something like this.
SELECT DaysRange=CASE
WHEN Datediff(DAY, LastModifiedDate, Getdate()) BETWEEN 30 AND 60 THEN '30-60'
WHEN Datediff(DAY, LastModifiedDate, Getdate()) BETWEEN 61 AND 90 THEN '61-90'
WHEN Datediff(DAY, LastModifiedDate, Getdate()) > 90 THEN '90+'
END,
CustomersCount=Count(1)
FROM yourtable
GROUP BY CASE
WHEN Datediff(DAY, LastModifiedDate, Getdate()) BETWEEN 30 AND 60 THEN '30-60'
WHEN Datediff(DAY, LastModifiedDate, Getdate()) BETWEEN 61 AND 90 THEN '61-90'
WHEN Datediff(DAY, LastModifiedDate, Getdate()) > 90 THEN '90+'
END
Using this query:
SELECT COUNT(CASE WHEN DATEDIFF(d, LastModifiedDate, getdate()) BETWEEN 30 AND 60 THEN 1 END) AS [30-60],
COUNT(CASE WHEN DATEDIFF(d, LastModifiedDate, getdate()) BETWEEN 61 AND 90 THEN 1 end) AS [61-90],
COUNT(CASE WHEN DATEDIFF(d, LastModifiedDate, getdate()) > 90 THEN 1 END) AS [90+]
FROM mytable
produces the following output:
30-60 61-90 90+
1 1 1
With UNPIVOT we get the desired result set:
SELECT DaysRange, CustomersCount
FROM (
SELECT COUNT(CASE WHEN DATEDIFF(d, LastModifiedDate, getdate()) BETWEEN 30 AND 60 THEN 1 END) AS [30-60],
COUNT(CASE WHEN DATEDIFF(d, LastModifiedDate, getdate()) BETWEEN 61 AND 90 THEN 1 END) AS [61-90],
COUNT(CASE WHEN DATEDIFF(d, LastModifiedDate, getdate()) > 90 THEN 1 END) AS [90+]
FROM mytable) p
UNPIVOT
(CustomersCount FOR DaysRange IN ([30-60], [61-90], [90+])
) AS unpvt;
Output:
DaysRange CustomersCount
30-60 1
61-90 1
90+ 1

SQL to Access - Sum Case to IFF

I have following SQL code that needs to be converted to MS Access SQL view.
sum(case when DATEDIFF(d, A.DUEDATE, getdate()) < 31
and A.TYPE < 7 then A.AMT
when DATEDIFF(d, A.DOEDATE1, getdate()) < 31
and A.TYPE > 6 then A.AMT *-1
else 0
end) [Current]
I'm stuck after this:
Sum(IIF(Datediff(d, A.DUEDATE, Now())<31
Is this what you are looking for?
Sum(IIF(Datediff(d, A.DUEDATE, Now()) < 31 AND A.Type < 7, A.AMT,
IIF(DATEDIFF(d, A.DOEDATE1, getdate()) < 31 and A.TYPE > 6, -A.AMT, 0
)
)

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