Using a Parameterized column in a Where Clause using Case - sql

I am building a report in SSRS where I need to be able to let our users filter on different date fields. They need to be able to select the date filter and then the start and end dates within that filter.
This is a simplified Example of what I am trying to achieve:
SELECT Project.ProjectID, Project.Name, Project.Update_Date, Project.Due_Date, Project.Start_Date, Project.Review_Date
FROM Project
WHERE #datetypefiler BETWEEN #startdate AND #enddate
Where the #datetypefiler will essentially equal the field the user wishes to filter on (i.e. Project.Update_Date or Project.Due_Date etc)
On SSRS i built parameters for #datetypefiler which could equal the various date fields and I set up the start date and end date filter as expected.
Unfortunately it does not seem as though I can parameterize the #datetypefiler in this way? I then attempted to use the Case keyword as so:
SELECT Project.ProjectID, Project.Name, Project.Update_Date, Project.Due_Date, Project.Start_Date, Project.Review_Date
FROM Project
WHERE CASE
when #datetypefiler='Project.Update_Date' then Project.Update_Date BETWEEN #startdate AND #enddate
when #datetypefiler='Project.Due_Date' then Project.Due_Date BETWEEN #startdate AND #enddate
This isnt working for me either, I figure that instead of taking shots in the dark I should ask what the correct method would look like. Any advice on this would be greatly appreciated,

You could try something like this:
SELECT *
FROM Project
WHERE (#datetypefiler='Project.Update_Date'
AND Project.Update_Date BETWEEN #startdate AND #enddate)
OR (#datetypefiler='Project.Due_Date'
AND Project.Due_Date BETWEEN #startdate AND #enddate)
The OR will only evaluate the full statement if the #datetypefiler is matched.

Or you could try this
SELECT Project.ProjectID, Project.Name, Project.Update_Date, Project.Due_Date,
Project.Start_Date, Project.Review_Date
FROM Project
where
(CASE
when #datetypefiler = 'Project.Update_Date' then Project.Update_Date
when #datetypefiler= 'Project.Due_Date' then Project.Due_Date
END) BETWEEN #startdate AND #enddate

While both of other two answers are going to work just fine, they won't make use of index. I'd recommend to have two separate SELECT statements with two different queries based on your criteria, this way you can index your table both on Update_Date and Due_Date and actually use them to speed your queries up.

Related

SSRS with a parameter #startdate

I currently have an SSRS report that runs daily with the below SQL code as it should. But, when replication goes down and we miss a day, our Court people would like to be able to manually run a missed date by entering a date #1.
I need some help with setting up the parameter #StartDate, that will run the code below.
I have this SQL:
Select *
from Court
WHERE
case_filed_dt =
CASE WHEN datepart(weekday,getdate())= 2 THEN
datediff(day,3,getdate())
ELSE
datediff(day,1,getdate())
END
Order by court asc
Simple case statement that looks at the date the report is run, if it runs on Monday's, it get Friday's data otherwise previous day's data.
I would like to add a parameter #startdate for my "case_filed_dt" field, to run manually, in case a report is missed.
Example:
If I run for #startdate = '06-06-2022' it will do as my case statement code does, and get data for '06-03-2022'. If I run for #startdate ='06-07-2022', data is for 6-06-2022'.
Thanks,
jer
I would keep this simple.
Change your existing dataset query to accept a parameter (pStartDate) like this..
Select *
from Court
WHERE
case_filed_dt =
CASE WHEN datepart(weekday, #pStartDate)= 2 THEN
datediff(day,3, #pStartDate)
ELSE
datediff(day,1, #pStartDate)
END
Order by court asc
Then in your report, set the parameter's default value to be an expression
=Today()
Then if the report is run as normal with no parameters passed, it will use Today() as the start date or if the report is run manually, any date can be selected by the user.
a few versions on the fiddle, which should get you started, this one using a variable to simulate the effects of the Case statement.
Change the date and see what happens
Declare #DateNow datetime = '2022-06-03'
SELECT #DateNow as YourDate, DATENAME(WEEKDAY, #DateNow) AS DayNow, '',
CASE
WHEN DATENAME(WEEKDAY, #DateNow) = 'Monday' THEN
DateAdd(day,-3,#DateNow)
ELSE
DateAdd(day,-1,#DateNow)
END AS ReportDate
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=b3ae703d3be9ace930822f7e20230018

SQL query based on two values in a column with a date range

So here is what I'm attempting to accomplish. I want to have returned all rows within a specified date range where the value in a column is one value 'C' or another 'X'. I'm not huge in SQL and much more comfortable in scriptwriting for excel or google sheets. I would assume there's a pretty simple solution but here is what I have written so far that's not working.
Declare #FromDate DateTime
Declare #ToDate DateTime
Set #FromDate='20201027'
Set #ToDAte ='20201102'
select * from oehdr where OrderStatus='C' or OrderStatus='X'
The errors I've received have been "Invalid SQL, No Memory" and a script error when I modify the current attempt.
There's not enough info in the question. We don't know the name of the date column, or whether the time is included, or whether the ToDate value is inclusive of the whole day. It's not even 100% clear exactly what DB you're using, as there's some conflicting info with the question.
But I'll do the best I can making some guessues:
Declare #FromDate DateTime = '20201027'
Declare #ToDate DateTime = '20201102'
SELECT *
FROM oehdr
WHERE OrderStatus IN ('C', 'X')
AND OrderDate >= #FromDate AND OrderDate < DATEADD(day, 1, #ToDate)
Notice I did not use the BETWEEN operator. BETWEEN is inclusive at both ends of the range, which is rarely what I want for dates. Instead, when I want the full day, I add one day and use an exclusive condition for the end of the range.

SQL Procedure use

Parameters are displaying an error and I typed them as follows:
where createdon between #startdate and #enddate
and pt.[state] in #([state])
and pt.carrier in (#Carrier)
and pt.LineOfBusiness IN (#LOB)
All these are added for the where clause
First, you are attempting to write:
where createdon between #startdate and #enddate and
pt.[state] in (#state) and
pt.carrier in (#Carrier) and
pt.LineOfBusiness in (#LOB)
This does not do what you want. Presumably you intend something like this:
where createdon >= #startdate and createdon < #enddate + interval 1 day and
pt.[state] = #state and
pt.carrier = #Carrier and
pt.LineOfBusiness = #LOB
Two notes:
in with a variable is exactly equivalent to =. So use that.
between ignores time components. Presumably, createdon has a time component, so this captures what is most likely your intended logic.
If you want to use in, then you cannot use a simple variable. Depending on the database, there may be way to implement a solution.

SQL query Performance when using Datetime in where / On clause

I have the 5l record in table. need to query...Which is one is query fast,Input parameter #RegistrationFrom DATE,#RegistrationTo DATE
Approach #1:
WHERE
CAST(Act.RegistrationOn AS DATE) BETWEEN CAST(#RegistrationFrom AS DATE)
AND CAST(#RegistrationTo AS DATE)
Approach #2 - convert into datetime:
DECLARE #From DATETIME, #Todate DATETIME;
SELECT #From = #RegistrationFrom;
SELECT #Todate = DATEADD(day, 1, #RegistrationTo);
WHERE
Act.RegistrationOn BETWEEN #From AND #Todate
Approach #3:
WHERE CONVERT(VARCHAR, Act.RegistrationOn,101) BETWEEN #From AND #Todate
I ma getting fast response approach 3 than above 1,2.
How it is working?
I would write the query as:
SELECT #Todate = DATEADD(day, 1, #RegistrationTo);
. . .
WHERE Act.RegistrationOn >= #From AND
Act.RegistrationOn < #Todate
Whether you use variables or a cast on the variable should have no or little affect on performance. More important considerations are the use of indexes and interpretability (does the code do what you intend).
Aaron Bertrand has a very good blog on why you shouldn't use BETWEEN for dates.
As for the first version . . . it is actually more reasonable than you might think. In general, function calls prevent the use of indexes on columns. However, SQL Server makes an exception for conversion of a datetime to date. So, it will still use an index.
That said, I would still go with the above version.
Try it like this:
WITH MyPrms AS
(
SELECT CAST(#RegistrationFrom AS DATE) AS fromD
,CAST(#RegistrationTo AS DATE) + 1 AS toD
)
SELECT *
FROM MyPrms
CROSS JOIN Act
WHERE Act.Registration>=fromD AND Act.RegistrationOn<toD;
It is fully inlineable (in VIEWS, functions...) and sargable (optimizer can use indexes)
EDIT just for clearity
By adding +1 to your upper border date (which was casted to a timeless DATE before, the upper border is midnight after the last day. By using a < you will get all data from the full day. BETWEEN includes the border which can lead to unexpected errors...
Both options are equivalent from performance point of view:
Approach 1
WHERE Act.RegistrationOn AS DATE BETWEEN CAST(#RegistrationFrom AS DATE) AND CAST(#RegistrationTo AS DATE)
Approach 2
WHERE RegistrationOn BETWEEN #From AND #Todate
Each casting in Approach 1 is executed only once and not for each row as you might expected.
For clarity, I would take option 2 or even better send the parameter with the right type to this query.
Also, an index on RegistrationOn column would definitively help. Please note a CAST on RegistrationOn column has been removed from Approach 1 as this would prevent SQL Server to use this index.
WHERE CONVERT(VARCHAR, Act.RegistrationOn,101) BETWEEN #From AND #Todate

how to use like and between in where clause in same statement?

Im trying to find a set of results in a database based on dates. The dates are stored as varchars in the format dd/mm/yyyy hh:mm:ss.
What i would like to do is search for all dates within a range of specified dates.
For example i tried:
SELECT * FROM table_name
WHERE fromDate BETWEEN LIKE '%12/06/2012%' AND LIKE '%16/06/2012%'
Is something like this possible or is there a better way of doing this type of statement, because so far i have had little success?
I'm using Microsoft SQL server 2008.
Peter
Since your date values also include time, you can't use BETWEEN. The only safe way to do this is:
SELECT <cols> FROM dbo.table_name
WHERE CONVERT(DATE, fromDate, 103) >= '20120612'
AND CONVERT(DATE, fromDate, 103) < '20120617';
But as Martin noticed, you'll never be able to use an index on that column, so this will always perform a full table scan.
If you really, really want to use BETWEEN, converting to DATE is the only safe way to do so (well, or trimming the time off in other, less efficient ways):
SELECT <cols> FROM dbo.table_name
WHERE CONVERT(DATE, fromDate, 103) BETWEEN '20120612' AND '20120616';
But for consistency reasons I recommend against between even in that case.
Try This
SELECT * FROM table_name
WHERE Convert(Date,fromDate,103)
BETWEEN '20120612' AND '20120616'
The best solution is to store your varchars as DateTime in the database.
Second best is to convert then to dates in the select (as the other answers just indicates so I am not going to give the example)
The following works fine for me. Try this:
SELECT *
FROM [MABH-Desi-Dera].[dbo].[Order]
WHERE (CONVERT(nvarchar,[Order_ID]) BETWEEN '200622%' AND '200623%')
Here the Order_IDs start with some Date:
hi man this is not a rocket science bro
just make a logic like
Blockquote
SELECT * FROM table_name
WHERE fromDate BETWEEN '2021-05-01 12:00:00' AND '2021-05-01 23:59:00'
Blockquote
it will work I stuck too but it helps. i was also trying make a logic like u