SQL to Access - Sum Case to IFF - sql

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
)
)

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'

Group by year in sql

I am trying to group by year but was not able to do.I can get the column count but not year wise. this is what i tried.
select t_contract ,
sum(CASE t_contract when '18' then 1 else 0 end) as XL,
sum(CASE t_contract when '01' then 1 else 0 end) as VC,
sum(CASE t_contract when '75' then 1 else 0 end) as AN,
sum(CASE t_contract when '48' then 1 else 0 end) as CS
from icps.dbo.tickets
WHERE
t_date_time_issued >= DATEADD(year, -6, GETDATE())
GROUP BY contract
.. but i want to add year .. where i have t_date_time _issued column.
My another query is I have a column called t_zone_name and I want to sum all the rows where t_zone_anme like '%ICeland%' an i tried this:
sum(CASE t_zone_name like '%ICeland%' then 1 else 0 end) as ICELAND
but I get an error on statement like... thanks in advance.
LIKE
YEAR XL VC AN CS total
2010 50 50 50 50 200
2011 5 5 5 5 20
Try the below query:
SELECT t_contract, YEAR(t_date_time_issued) As Yr, SUM(CASE WHEN t_zone_name like '%ICeland%' THEN 1 ELSE 0 END) AS ICELAND
SUM(CASE t_contract when '18' then 1 else 0 end) as XL,
SUM(CASE t_contract when '01' then 1 else 0 end) as VC,
SUM(CASE t_contract when '75' then 1 else 0 end) as AN,
SUM(CASE t_contract when '48' then 1 else 0 end) as CS
FROM icps.dbo.tickets
WHERE YEAR(t_date_time_issued) >= (YEAR(GetDate()) - 6)
GROUP BY t_contract, YEAR(t_date_time_issued)
You might need change the order of t_contract and YEAR(t_date_time_issued) depending on which grouping you want to apply first.
As suggested by #ray I have replaced DATEPART(yyyy, t_date_time_issued) >= DATEPART(yyyy, DATEADD(year, -6, GETDATE())) with year(t_date_time_issued) >= (year(GetDate()) - 6)
If you want to group by year, in sql server, you might
GROUP BY DATEDIFF(year,t_date_time_issued, GETDATE())
In other DB engine, usually has method to get year part, or use substring to get year part from a time string.

SQL -- Show results only when count's higher than xx

So far I have this written:
SELECT
Query,
SUM(CASE WHEN SearchDate >= '2012-01-01' and SearchDate < '2013-01-01' THEN 1 ELSE 0 END) as Year2012,
SUM(CASE WHEN SearchDate >= '2013-01-01' and SearchDate < '2014-01-01' THEN 1 ELSE 0 END) as Year2013
FROM dbo.tblSearch WITH (NOLOCK)
WHERE DomainProjectID=13
GROUP BY Query
It looks at the query (search) terms in the table and counts how many times each appears in the given date range (in this case, this year and last).
In the results, I want to only show those that appear 100 times or more. Right now it's showing all.
Query Year2012 Year2013
beavers 90 87
hair 4 14
If the best method of doing this doesn't involve CASE WHEN, please let me know! Beginner here.
Use an additional having clause
SELECT
Query,
SUM(CASE WHEN SearchDate >= '2012-01-01' and SearchDate < '2013-01-01' THEN 1 ELSE 0 END) as Year2012,
SUM(CASE WHEN SearchDate >= '2013-01-01' and SearchDate < '2014-01-01' THEN 1 ELSE 0 END) as Year2013
FROM dbo.tblSearch WITH (NOLOCK)
WHERE DomainProjectID=13
GROUP BY Query
having
SUM(CASE WHEN SearchDate >= '2012-01-01' and SearchDate < '2014-01-01'
THEN 1
ELSE 0
END) >= 100
I think this is a little clearer and easier to maintain:
SELECT
Query,
SUM(CASE WHEN year(SearchDate) = 2012 THEN 1 ELSE 0 END) as Year2012,
SUM(CASE WHEN year(SearchDate) = 2013 THEN 1 ELSE 0 END) as Year2013
FROM dbo.tblSearch WITH (NOLOCK)
WHERE DomainProjectID=13
GROUP BY Query
having
SUM(CASE WHEN year(SearchDate) in (2012, 2013) THEN 1 ELSE 0 END)
>= 100

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