CASE WHEN using AND statement in SQL - sql

I have a query like this :
SELECT
CASE
WHEN (CONVERT(INT, (datepart(DD, A.CIDATE))) AND Year(getDate()) = 2016 ) <= 15
THEN CONVERT(INT,(datepart(MM,A.CIDATE)))
WHEN CONVERT(INT, (datepart(DD, A.CIDATE))) > 15
THEN CONVERT(INT, (datepart(MM, A.CIDATE))) + 1
ELSE 0
END AS MASA_PAJAK
FROM
V_CLAIM_INTERNAL A
It's working but when I add AND Year(getDate()) = 2016 it throws an error:
Msg 4145, Level 15, State 1, Line 1
An expression of non-boolean type specified in a context where a condition is expected, near 'AND'.
I try to make convert also but still having the same error.
SELECT
CASE
WHEN ((CONVERT(INT, (datepart(DD, A.CIDATE))) AND (convert(int, Year(getDate()) = 2016 ))) <= 15
THEN CONVERT(INT, (datepart(MM, A.CIDATE)))
WHEN CONVERT(INT, (datepart(DD, A.CIDATE))) > 15
THEN CONVERT(INT, (datepart(MM, A.CIDATE))) + 1
ELSE 0
END AS MASA_PAJAK
FROM
V_CLAIM_INTERNAL A
What is my query mistake :?

This is probably what you are intending to do:
SELECT CASE WHEN DATEPART(DD, A.CIDATE) <= 15 AND YEAR(GETDATE()) = 2016
THEN DATEPART(MM, A.CIDATE)
WHEN DATEPART(DD, A.CIDATE) > 15
THEN DATEPART(MM, A.CIDATE) + 1
ELSE 0
END AS MASA_PAJAK
FROM V_CLAIM_INTERNAL A
Note that you don't need to convert/cast the result of calling DATEPART, because it already returns an integer.

SELECT CASE
WHEN (CONVERT(INT,(datepart(DD,A.CIDATE)))<= 15 AND Year(getDate()) = 2016 ) THEN CONVERT(INT,(datepart(MM,A.CIDATE)))
WHEN CONVERT(INT,(datepart(DD,A.CIDATE))) > 15 THEN CONVERT(INT,(datepart(MM,A.CIDATE)))+1
ELSE 0 END AS MASA_PAJAK
FROM V_CLAIM_INTERNAL A

Try this Query:
SELECT CASE WHEN datepart(DD,A.CIDATE)<= 15 AND
Year(getDate()) = 2016
THEN datepart(MM,A.CIDATE)
WHEN datepart(DD,A.CIDATE) > 15
THEN datepart(MM,A.CIDATE) + 1
ELSE 0
END AS MASA_PAJAK
FROM V_CLAIM_INTERNAL A

Related

How to query all rows that are due the next business day?

If it helps, I'm using BytePro which I believe is using T-SQL based on the statement they've generated.
I'm having an issue where when I try retrieving data, I need to switch based on the day of the week. (current day being today's date using GetDate()).
M-T statement:
convert(varchar(10), [Status.SchedFundingDate], 112) <= convert(varchar(10), getdate() + 1, 112)
F statement:
convert(varchar(10), [Status.SchedFundingDate], 112) <= convert(varchar(10), getdate() + 3, 112)
I'd like to combine the two to automate the switch but I get a problem with
CAST(CASE
WHEN DATENAME(DW, GETDATE()) = 'Friday'
AND [Status.SchedFundingDate] <= GETDATE() + 3
THEN 1
WHEN [Status.SchedFundingDate] <= GETDATE() + 1
THEN 1
ELSE 0
END AS BIT)
I get an error:
An expression of non-boolean type specified in a context where a condition is expected, near 'AND'
this is the right syntax :
CAST(CASE WHEN DATENAME(DW, GETDATE()) = 'Friday'
AND [Status].[SchedFundingDate] <= DATEADD(DAY, 3 , GETDATE())
THEN 1
WHEN [Status].[SchedFundingDate] <= DATEADD(DAY, 1 , GETDATE())
THEN 1
ELSE 0
END AS BIT)
db<>fiddle here

simplify a SQL case statement in a case expression

How would I simplify this case statement in T-SQL? It provides the desired result, but it's very unwieldy and hard to read. I have to use the inner case statement to convert a Julian date (aka 6 digit number) into a regular date format.
Basically i'm doing a datediff( getdate(), case statement). Getdate() just returns the time now (ie. 2/27/2020) and the case statement converts a julian date (ie. 123456) into a normal date (ie, 1/1/2020).
Here's the expect output if the query was ran today on Feb 27.
Select CASE
WHEN Datediff(day, Getdate(), CASE
WHEN a.wadpl = 0
THEN NULL
ELSE Dateadd(d, Substring(Cast(wadpl AS VARCHAR(6)), 4, 3) - 1, CONVERT(DATETIME, CASE
WHEN LEFT(Cast(wadpl AS VARCHAR(6)), 1) = '1'
THEN '20'
ELSE '21'
END + Substring(Cast(wadpl AS VARCHAR(6)), 2, 2) + '-01-01'))
END) < 0
THEN 'Overdue Now'
WHEN Datediff(day, Getdate(), CASE
WHEN a.wadpl = 0
THEN NULL
ELSE Dateadd(d, Substring(Cast(wadpl AS VARCHAR(6)), 4, 3) - 1, CONVERT(DATETIME, CASE
WHEN LEFT(Cast(wadpl AS VARCHAR(6)), 1) = '1'
THEN '20'
ELSE '21'
END + Substring(Cast(wadpl AS VARCHAR(6)), 2, 2) + '-01-01'))
END) <= 30
THEN 'Coming due in 01-30 days'
ELSE 'Not Overdue'
END [Overdue Status]
FROM Table_X
Here is a easy one to understand, assuming a.wadpl is an integer:
SELECT CASE
WHEN DATEDIFF(DAY, GETDATE(), DATEADD(DAY, a.wadpl % 1000, DATEADD(YEAR,a.wadpl / 1000,'1899-12-31'))) <0 THEN 'Overdue now'
WHEN DATEDIFF(DAY, GETDATE(), DATEADD(DAY, a.wadpl % 1000, DATEADD(YEAR,a.wadpl / 1000,'1899-12-31'))) <= 30 THEN 'Coming due in 01-30 days'
ELSE 'Not Overdue'
END [Overdue Status]
FROM Table_X
or you can simplify by using a subquery (or you can use a WITH):
SELECT CASE
WHEN Age <0 THEN 'Overdue now'
WHEN Age <= 30 THEN 'Coming due in 01-30 days'
ELSE 'Not Overdue'
END [Overdue Status]
FROM (
SELECT DATEDIFF(DAY,GETDATE(),
DATEADD(DAY,wadpl%1000,DATEADD(YEAR,wadpl/1000,'1899-12-31'))) Age, *
FROM Table_X) a
This will of course cause you to do this arithmetic for each row, and you can't easily use any indexes. If you were asking about aggregates, then I would suggest doing the opposite, and pre-calculating the dates and use those in your query instead. You might also want to consider putting a persisted computed column on table_x:
ALTER TABLE TABLE_X
ADD wadpl_dt AS
(DATEADD(DAY,wadpl%1000,DATEADD(YEAR,wadpl/1000,'1899-12-31'))) PERSISTED;
Now you can just refer to table_x.wadpl_dt whenever you want the datetime, and your query would become:
SELECT CASE
WHEN Age <0 THEN 'Overdue now'
WHEN Age <= 30 THEN 'Coming due in 01-30 days'
ELSE 'Not Overdue'
END [Overdue Status]
FROM (
SELECT DATEDIFF(DAY,GETDATE(), wadpl_dt) Age, *
FROM Table_X) a
Here is the easy way to convert a date to what you refer to as the julian date:
SELECT (DATEPART(YEAR,GETDATE())-1900) * 1000 + DATEPART(DAYOFYEAR, GETDATE())
And this is how you can use it:
DECLARE #overdue int;
DECLARE #next30 int;
SET #overdue = (SELECT (DATEPART(YEAR,GETDATE())-1900) * 1000 + DATEPART(DAYOFYEAR, GETDATE()));
SET #next30 = (SELECT (DATEPART(YEAR,GETDATE()+30)-1900) * 1000 + DATEPART(DAYOFYEAR, GETDATE()+30));
SELECT CASE
WHEN wadpl < #overdue THEN 'Overdue now'
WHEN wadpl <= #next30 THEN 'Coming due in 01-30 days'
ELSE 'Not Overdue'
END [Overdue Status]
FROM Table_X

sql if statement not working

I can't get this if statement to work.
I'm trying to say 'if(number of dates) is greater than 330, return 'x', otherwise give me the (number of dates)
SELECT if(ROUND(COUNT(ClosedDate) / 10, 0) * 10 > 330 then 'X' else ROUND(COUNT(ClosedDate) / 10, 0) * 10) end AS [Previous Day Sales]
FROM PartsSales
WHERE (MONTH(ClosedDate) = MONTH(GETDATE()))
AND (YEAR(ClosedDate) = YEAR(GETDATE()))
AND (DAY(ClosedDate) = DAY(GETDATE() - 13))
Use a CASE clause:
SELECT CASE WHEN ROUND(COUNT(ClosedDate) / 10, 0) * 10 > 330 then 'X' else ROUND(COUNT(ClosedDate) / 10, 0) * 10 end AS [Previous Day Sales]
FROM PartsSales
WHERE (MONTH(ClosedDate) = MONTH(GETDATE())) AND (YEAR(ClosedDate) = YEAR(GETDATE())) AND (DAY(ClosedDate) = DAY(GETDATE() - 13))
Use CASE:
SELECT
CASE WHEN ROUND(COUNT(ClosedDate) / 10, 0) * 10 > 330
THEN 'X' ELSE ROUND(COUNT(ClosedDate) / 10, 0) * 10) END AS [Previous Day Sales]
FROM PartsSales
WHERE MONTH(ClosedDate) = MONTH(GETDATE())
AND YEAR(ClosedDate) = YEAR(GETDATE())
AND DAY(ClosedDate) = DAY(GETDATE() - 13)
I would recommend:
SELECT (CASE WHEN COUNT(*) >= 335 THEN 'X'
ELSE CAST(ROUND(COUNT(ClosedDate) / 10, 0) * 10) as VARCHAR(255))
END) AS [Previous Day Sales]
FROM PartsSales ps
WHERE CAST(ClosedDate as DATE) = CAST(DATEADD(day, -13, GETDATE()) as DATE);
Notes:
You WHERE clause is too complicated.
Why is the "previous day" using the day from 13 days ago?
Be explicit about the types! You are mixing strings and numbers. The result of the case expression needs to be a string.

create fiscal week number

How can I put the below logic into a format SQL Server will use to create a fiscal week number ?
if (datepart(week,getdate())-4) <= 0 then (datepart(week,getdate())+49) else (datepart(week,getdate())-4)
The CASE Statement should work:
CASE
WHEN (datepart(week,getdate())-4) <= 0
THEN datepart(week,getdate())+49
ELSE
datepart(week,getdate())-4
END
You could use a case expression:
SELECT CASE WHEN (DATEPART(WEEK, getdate()) - 4) <= 0
THEN DATEPART(WEEK, getdate()) + 49
ELSE DATEPART(WEEK, getdate()) - 4
END
For SQL Server 2012+, you can use IIF
SELECT IIF((datepart(week, getdate())-4) <= 0, datepart(week, getdate()) + 49, datepart(week, getdate()) - 4 )
For Less than SQL Server 2012 version, you may use CASE.

I want to get number of CenterMeeting between give two date on that case

case when #mode='TwoDays'
then CenterMeetingDay between datepart(dw,GETDATE()-1) and DATEPART(DW,GETDATE()+1)
end CenterMeetingDay
In SQL Server, you cannot simply put a boolean comparison as the when clause.
So, include the condition in the when and be explicit about the return values:
(case when #mode = 'TwoDays' and
CenterMeetingDay between datepart(dw, GETDATE() - 1) and DATEPART(DW, GETDATE() + 1)
then 1 else 0
end) as CenterMeetingDay
In a where clause, you can do:
where ( (#mode = 'TwoDays') and CenterMeetingDay between datepart(dw, GETDATE() - 1) and DATEPART(DW, GETDATE() + 1)) or
( (#mode <> 'TwoDays' . . . )
or:
where (case when #mode = 'TwoDays' and
CenterMeetingDay between datepart(dw, GETDATE() - 1) and DATEPART(DW, GETDATE() + 1)
then 1 else 0
end) = 1