Obtaining columns values only if date > today - sql

I have a query where i need to get values in 4 columns but only if the date is greater than today from a 5th column. I have tried the following but it doesn't seem to be working.
Select
(case when clientplans.END_DATE < convert(date,getdate(,101) then '') else insplans.Desc_upper as PLAN NAME,
(case when clientplans.END_DATE < convert(date,getdate(,112) then '') else insplans.ID_NO,
(case when clientplans.END_DATE < convert(date,getdate(,112) then '') else insplans.cert_NO,
I have converted the date on the end date as follows:
convert (varchar,clientplans.END_DATE,112) as POLICY_EXP_DATE,
does it matter that I do the conversion of the end date later in the query? the clientplans.end_date has to be inserted into the results in a certain order which happens to be after the description, id and cert number. Thanks for any help.

Perhaps something like this does what you want:
Select (case when cp.END_DATE > cast(getdate() as date) then insplans.Desc_upper end) as PLAN_NAME,
(case when cp.END_DATE > cast(getdate() as date) then insplans.ID_NO end) as ID_NO,
(case when cp.END_DATE > cast(getdate() as date) then insplans.cert_NO END) as cert_NO
from clientplans cp . . .
Note the following:
This table uses table aliases (cp for clientplans), so the query is easier to write and to read.
It uses cast() to a date to just get the date.
Non-matching rows are given a NULL value instead of ''. That usually makes more sense.
EDIT:
Of course, you can use '', if you like:
Select (case when cp.END_DATE > cast(getdate() as date) then insplans.Desc_upper else '' end) as PLAN_NAME,
(case when cp.END_DATE > cast(getdate() as date) then insplans.ID_NO else '' end) as ID_NO,
(case when cp.END_DATE > cast(getdate() as date) then insplans.cert_NO else '' end) as cert_NO,
(case when cp.END_DATE > cast(getdate() as date)
then convert(varchar(255), cp.StartDate, 121) else ''
end) as StartDate
from clientplans cp . . .

Use this to get the start of today: DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)
For example:
SELECT DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)
And for yours...
Select
(case when clientplans.END_DATE > DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0) then '') else insplans.Desc_upper as PLAN NAME,
(case when clientplans.END_DATE > DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0) then '') else insplans.ID_NO,
(case when clientplans.END_DATE > DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0) then '') else insplans.cert_NO,

i think proper casting is required So I Used Here CAST(Field as DATE) and
in Your Query getdate(,101) is wrong syntax
Select
(case when CAST(clientplans.END_DATE as date) < CAST(getdate() as date) then '')
else insplans.Desc_upper as PLAN NAME,
(case when CAST(clientplans.END_DATE as date) < CAST(getdate() as date) then '')
else insplans.ID_NO,
(case when CAST(clientplans.END_DATE as date) < CAST(getdate() as date) then '')
else insplans.cert_NO

You can use cursor on the 5th column
and check #cursor_date> is greater than today.
Only then will get the rest of the 4 columns.

Related

Create view with variable declaration defined by a case expression, generating a dynamic date table based on getdate() reference

I have static date table and a working query that I use to add references fields for comparison between financial periods, I would like to save as a view however the variable declaration is not permitted.
Query is shown below, the specific issues is with declaring "#this_qtr_month" and calculating "Is QTD". The variable determines [Num of Month in QTR] for today.
declare #this_qtr_month as int = case when month(getdate()) in (1,4,7,10) then 1
when month(getdate()) in (2,5,8,11) then 2
when month(getdate()) in (3,6,9,12) then 3
end
select *
,DATEDIFF(day,[Date],getdate()) as 'Days Aged'
,DATEDIFF(ww,[Date],getdate()) as 'Weeks Aged'
,DATEDIFF(qq,[Date],getdate()) as 'QTRs Aged'
,DATEDIFF(yy,[Date],getdate()) as 'Years Aged'
,case when DATEPART(dd,[Date]) <= DATEPART(dd,getdate()) then 'Y' else 'N' end as 'Is MTD'
,case when #this_qtr_month > [Num of Month in QTR] then 'Y'
when #this_qtr_month = [Num of Month in QTR] and DATEPART(dd,[Date]) <= DATEPART(dd,getdate()) then 'Y'
else 'N'
end as 'Is QTD'
,case when getdate() >= DATEFROMPARTS(year(getdate()), [Month Num], day(date_modified_LeapYear)) then 'Y' else 'N' end as 'Is YTD'
from Date_Table_Static
You could write that without a variable:
SELECT *,
DATEDIFF(DAY, [Date], GETDATE()) AS 'Days Aged',
DATEDIFF(ww, [Date], GETDATE()) AS 'Weeks Aged',
DATEDIFF(qq, [Date], GETDATE()) AS 'QTRs Aged',
DATEDIFF(yy, [Date], GETDATE()) AS 'Years Aged',
CASE
WHEN DATEPART(dd, [Date]) <= DATEPART(dd, GETDATE()) THEN
'Y'
ELSE
'N'
END AS 'Is MTD',
CASE
WHEN (CASE
WHEN MONTH(GETDATE()) IN ( 1, 4, 7, 10 ) THEN
1
WHEN MONTH(GETDATE()) IN ( 2, 5, 8, 11 ) THEN
2
WHEN MONTH(GETDATE()) IN ( 3, 6, 9, 12 ) THEN
3
END
) > [Num of Month in QTR] THEN
'Y'
WHEN (CASE
WHEN MONTH(GETDATE()) IN ( 1, 4, 7, 10 ) THEN
1
WHEN MONTH(GETDATE()) IN ( 2, 5, 8, 11 ) THEN
2
WHEN MONTH(GETDATE()) IN ( 3, 6, 9, 12 ) THEN
3
END
) = [Num of Month in QTR]
AND DATEPART(dd, [Date]) <= DATEPART(dd, GETDATE()) THEN
'Y'
ELSE
'N'
END AS 'Is QTD',
CASE
WHEN GETDATE() >= DATEFROMPARTS(YEAR(GETDATE()), [Month Num], DAY(date_modified_LeapYear)) THEN
'Y'
ELSE
'N'
END AS 'Is YTD'
FROM Date_Table_Static;
Or, since all you need with this view is a SELECT, you could write that as a Stored Procedure or TVF (Table Valued Function).
EDIT: I didn't read your expression before, it doesn't need to be that complex:
SELECT *,
DATEDIFF(DAY, [Date], GETDATE()) AS 'Days Aged',
DATEDIFF(ww, [Date], GETDATE()) AS 'Weeks Aged',
DATEDIFF(qq, [Date], GETDATE()) AS 'QTRs Aged',
DATEDIFF(yy, [Date], GETDATE()) AS 'Years Aged',
CASE
WHEN DATEPART(dd, [Date]) <= DATEPART(dd, GETDATE()) THEN
'Y'
ELSE
'N'
END AS 'Is MTD',
CASE
WHEN (Month(Getdate())-1)%3+1 > [Num of Month in QTR] THEN
'Y'
WHEN (Month(Getdate())-1)%3+1 = [Num of Month in QTR]
AND DATEPART(dd, [Date]) <= DATEPART(dd, GETDATE()) THEN
'Y'
ELSE
'N'
END AS 'Is QTD',
CASE
WHEN GETDATE() >= DATEFROMPARTS(YEAR(GETDATE()), [Month Num], DAY(date_modified_LeapYear)) THEN
'Y'
ELSE
'N'
END AS 'Is YTD'
FROM Date_Table_Static;

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

SSRS - Row visibility expression

I am using SSRS 2014.
I want to display only first 50 rows. What will be the expression for this please.
I used top n functionality it doesn't work. So I thought to take another route to achieve the result via expression.
Below image with out adding 'top n'. In the below image I wanted to display only first 50 rows in Supplier column
Below image with adding 'top n'. Then results are changed. Few rows in Concession column are missing.
SQL code is,
SELECT s.[CusNo] Supplier,
RTRIM(CAST(s.[Customer] AS VARCHAR(50)) ) AS Name,
s.[ConcessionNo] Concession,
RTRIM(CAST(s.[ConcessionName] AS VARCHAR(50)) ) AS ConcessionName,
sum(case when s.Date between convert(date,dateadd(wk, datediff(wk, 0, getdate()) - 1, 0) - 1) and convert(date,dateadd(wk, datediff(wk, 0, getdate()) - 1, 0) + 5)
then s.SELLINC else 0 end) ActualSales,
sum(case when s.Date
BETWEEN
convert(varchar(10), DATEADD(day, DATEDIFF(day, '19000107', DATEADD(month, DATEDIFF(MONTH, 0, CONVERT(date, CONVERT(VARCHAR(4), (CASE WHEN MONTH(GetDate()) = 1 THEN CONVERT(VARCHAR(4), GetDate(), 112) - 1 ELSE CONVERT(VARCHAR(4), GetDate(), 112) END), 112) + '0101')), 30)) / 7 * 7, '19000107'), 120)
AND
Convert(date, dateadd(wk, datediff(wk, 0, GETDATE()) - 1, 0) + 5)
then s.SELLINC else 0 end) YrToDateActual
FROM [dbo].[CustomerReports] s
WHERE s.BRN = 1 or s.BRN = 2 or s.BRN = 3 or s.BRN = 4 or s.BRN = 5 or s.SELLINC is null or s.SELLINC = '0'
GROUP BY s.[CusNo], s.[Customer], s.ConcessionNo, s.ConcessionName
order by YrToDateActual desc
Any help please?
If you want the first 50 suppliers, you should be able to use the following expression in the row visibility property:
=RunningValue(Fields!Supplier.Value, CountDistinct,"YourDataset") > 50
The report should perform better if you put this expression as a filter on the group instead of a row visibility expression, but at the moment I can't test to confirm whether this expression would be allowed there.
Modify your ORDER BY clause to:
ORDER BY s.[CusNo], YrToDateActual desc

How to use CASE in SELECT and WHERE clause to Eliminate divide by zero issue

Using SQL Server 2008 R2, I have a query which is now giving me a divide by zero error. This is because of a DB column value which was always supposed to be > 0. This has been changed. The column is wf.reminderFrequency and is now set to no nulls with a default value of 0.
Here is the query :
SELECT
wfi.WebFormsInstanceID AS instanceID,
wfi.FormActionDate as fLastActionDate,
wf.reminderFrequency as fReminderFeq,
DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE),
CAST(GETDATE() AS DATE)) AS theDateDiffCalc,
DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE),
CAST(GETDATE() AS DATE)) % wf.reminderFrequency AS theModCalc
FROM
(webFormsInstances as wfi
LEFT OUTER JOIN
WebFormsIndex as wf ON wfi.WebFormsIndexID = wf.WebFormsIndexID)
WHERE
(wfi.formStage <> 'Complete'
AND wfi.FormStage <> 'Terminated'
AND wfi.FormStage <> 'Payroll Processing')
AND (wfi.FormActionDate > 20150101)
AND (DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE), CAST(GETDATE() AS DATE)) % wf.reminderFrequency = 0)
ORDER BY
wfi.WebFormsInstanceID DESC;
The query is designed to get all the WebFormsIndex records where no action (difference between today and fLastActionDate) has happened in X (wf.reminderFrequency) number of days. Please note - The query is more confusing than it needs to be because fLastActionDate is an YYYYMMDD integer value which unfortunately can not be changed. So how do I change this to handle the scenario where wf.reminderFrequency can now be 0. As you can see this value is being used in a two divisions n the query.
This is my solution for the SELECT part which I think is going to work:
SELECT
wfi.WebFormsInstanceID AS instanceID,
wfi.WebFormsIndexID as fID,
wf.FormName as fName,
wfi.FormOwner as fOwner,
wfi.FormStage as fStage,
wfi.FormAction as fAction,
wfi.FormActionDate as fLastActionDate,
wf.reminderFrequency,
wfi.Comments as fComments,
DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE),
CAST(GETDATE() AS DATE)) AS theDateDiffCalc,
CASE
WHEN wf.reminderFrequency > 0
THEN
DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE), CAST(GETDATE() AS DATE)) % wf.reminderFrequency
ELSE
'-1'
END AS theModCalc
FROM
(webFormsInstances as wfi
But I am having no luck figuring out how to handle the division in the WHERE clause.
This does not work:
WHERE
(wfi.formStage <> 'Complete'
AND wfi.FormStage <> 'Terminated'
AND wfi.FormStage <> 'Payroll Processing')
AND (wfi.FormActionDate > 20150101)
CASE
WHEN wf.reminderFrequency > 0
THEN
AND (DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE), CAST(GETDATE() AS DATE)) % wf.reminderFrequency = 0)
END AS
ORDER BY
wfi.WebFormsInstanceID DESC;
UPDATE - Sample data from the first statement:
instanceID fLastActionDate fReminderReq theDateDiffCalc theModCalc
24965 20150312 14 14 0
24965 20150312 14 14 0
24940 20150226 14 28 0
Thanks to #Gordon using nullif was the solution. Seems to work very well. It was used like so in the select:
DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE),CAST(GETDATE() AS DATE)) % nullif(wf.reminderFrequency,0) AS theModCalc
and like so in the WHERE:
AND (DATEDIFF(day, CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE),CAST(GETDATE() AS DATE)) % nullif(wf.reminderFrequency,0) = 0)
If you can handle NULL as the value instead of -1, I would recommend NULLIF():
DATEDIFF(day,
CAST(CAST(wfi.formActionDate AS VARCHAR(8)) AS DATE),
CAST(GETDATE() AS DATE)
) % nullif(wf.reminderFrequency, 0) AS theModCalc
This will work in both the select and the where.