How to select dates in MSSQL - sql

I am trying to writing a query which can return a result if date time column(fromdate) is either null or fromdate is before a current date. Here is my query:
select * from patients where from date =null OR from date <= cast(cast(getdate() as date)as datetime)
but this query returning empty result. Can someone confirm me both checking null OR before currentDate check in query is valid or not ?
---------Apply filter on more than 1 column:-----------
SELECT *
FROM patients
WHERE(fromDate = NULL
OR t1.fromDate <= CONVERT(DATE, GETDATE()))
AND (t1.toDate = NULL
OR t1.toDate >= CONVERT(DATE, GETDATE()));
I have a null column in todate in table but apply like this give me empty result

This will work for you
SELECT *
FROM patients
WHERE fromdate IS NULL
OR fromdate <= CONVERT(DATE, GETDATE());

You would do:
select p.*
from patients p
where p.fromdate is null or p.fromdate <= cast(getdate() as date);
Notes:
According to your question fromdate does not have a space in it.
The correct comparison for NULL is IS NULL, not = NULL.
There is no need to cast a date back to a datetime for the comparison.

Try this:
select * from patients where [fromdate] is null OR [fromdate] <= cast(getdate() as datetime)

Related

Recursive CTE Returns Value Outside of Range

While searching for a method to create date ranges I came across a problem with the following query:
DECLARE #StartDate DateTime = '2000-01-01 01:00';
DECLARE #EndDate DateTime = '2020-01-01 00:00';
with Dates as (
select
#StartDate fromDate
UNION ALL
(Select
fromDate = dateadd(day, 1, #EndDate)
from
Dates
where
fromDate >= #StartDate AND
fromDate < #EndDate ))
Select * from Dates
OPTION (MAXRECURSION 0);
The following query returns two rows, one of which is outside of the range,
fromDate
-----------------------
2000-01-01 01:00:00.000
2020-01-02 00:00:00.000
I am aware that there is a way to fix this issue by changing the second half of the query to be different, for example:
Select * from Dates Where fromDate <= #EndDate
I have the following questions:
what is wrong with the query as is?
Why is it that this query returns two values, one of which lies outside the range provided?
This is using Microsoft SQL Server 2008 R2
Because your Recursive CTE add one day from fromDate
Select
fromDate = dateadd(day, 1, #EndDate)
but your condition filter fromDate
where
fromDate >= #StartDate AND
fromDate < #EndDate ))
If you want to do make calendar table by Recursive CTE.
you can try this.
with Dates as (
select #StartDate fromDate,#EndDate endDate
UNION ALL
Select
fromDate = dateadd(day, 1, fromDate),endDate
from
Dates
where
dateadd(day, 1, fromDate) <= #EndDate
)
Select * from Dates
OPTION (MAXRECURSION 0);
The simple answer for #1 / #2: You are selecting DATEADD(day, 1, #endDate) -- which, by definition, is 1 day 'over' your date range.
The real answer: To get the result you want, change:
(Select
fromDate = dateadd(day, 1, #EndDate)
To:
(Select
fromDate = dateadd(day, 1, fromDate)

Add a date range to SQL query

I have simple SQL Server view that I need to make amends to:
CREATE VIEW [dbo].[ApplicantStat]
AS SELECT ISNULL(CONVERT(VARCHAR(50), NEWID()), '') AS Pkid,
AVG(ApplicationTime) AS 'AvgApplicationTime',
AVG(ResponseTime) AS 'AvgResponseTime',
CAST(ROUND(100.0 * count(case when [IsAccepted] = 1 then 1 end) / count(case when [IsValid] = 1 then 1 end), 0) AS int) AS 'AcceptRate'
FROM [Application]
It works as planned, but I need to add a date range to it. It's not quite as simple as Where > this date and < that date, instead I need to create a range.
Suppose I have a 'CreatedOn' date in my Application table. I want to be able to include all rows from the last full day (yesterday) and work back 30 days (inclusive).
I'm using SQL Server 2014.
Use :
where CreatedOn between cast(getdate()-30 as date) and cast(getdate()-1 as date)
Please notice CAST is used, it is because to get the full day ignoring the time part.
Something like this:
where MyColumn between dateadd(dd, -1, convert(date, getdate())) and dateadd(dd, -30, convert(date, getdate()))
It's a bit beyond the scope of this question, but maybe useful to some. I like this way of creating a table with date range, to use in queries:
USE MyDataBase
DECLARE #StartDate DATE
DECLARE #EndDate DATE
SET #StartDate = '2014-01-01' -- << user input >> --
SET #EndDate = '2036-12-31' -- << user input >> --
IF OBJECT_ID ('TEMPDB..#Date') IS NOT NULL DROP TABLE #Date
IF OBJECT_ID ('TEMPDB..#Date') IS NULL CREATE TABLE #Date (DateOne DATE)
INSERT INTO #Date VALUES (#StartDate)
WHILE #StartDate < #EndDate
BEGIN
INSERT INTO #Date
SELECT DATEADD (DD, 1, #StartDate) AS Date
SET #StartDate = DATEADD (DD, 1, #StartDate)
END
SELECT * FROM #Date
You should be able to just stick a WHERE with a BETWEEN clause on the end.
CREATE VIEW [dbo].[ApplicantStat]
AS SELECT ISNULL(CONVERT(VARCHAR(50), NEWID()), '') AS Pkid,
AVG(ApplicationTime) AS 'AvgApplicationTime',
AVG(ResponseTime) AS 'AvgResponseTime',
CAST(ROUND(100.0 * count(case when [IsAccepted] = 1 then 1 end) / count(case when [IsValid] = 1 then 1 end), 0) AS int) AS 'AcceptRate'
FROM [Application]
WHERE CreatedOn BETWEEN GETDATE()-1 AND GETDATE()-30

Group By query for date based on Custom Time Period

I'm building a WCF application for calculating total time spend between in and out time, to fetch data from database I'm using GROUP BY clause to group data by date, but I want my day to start & end at 6:00 AM so if anyone leaves at 3 in the morning, it'll be added in the current day only. I'm using the following command query
SELECT MIN([Swipedatetime]) AS [Entry]
, MAX([Swipedatetime]) AS [Exit]
, [UserID]
FROM [Database_Name].[dbo].[Table_Name]
where UserID = '100'
GROUP
BY UserID
, CAST (Swipedatetime as DATE)
ORDER
BY MIN([Swipedatetime])
Also If there is any way by which the difference between the two times can be calculated in the stored procedure only then please mention it, it'll be of great use.
How about deducting 6 hours from the Swipedatetime and grouping by that new value:
GROUP BY (Swipedatetime - INTERVAL '6 hours')
(this is postgresql, for sql-server I think you need the function dateadd(hour, -6, Swipedatetime), or something along this line)
Your solution need only simple DATEADD function:
SELECT MIN([Swipedatetime]) AS [Entry]
, MAX([Swipedatetime]) AS [Exit]
, [UserID]
FROM [dbo].[Table_Name]
WHERE UserID = '100'
GROUP
BY UserID
, CAST (DATEADD(HOUR,6,Swipedatetime) AS DATE)
ORDER
BY MIN([Swipedatetime])
To get only records between 6am and 6pm you can use this:
where datepart(hour,[Swipedatetime]) > 6
and datepart(hour,[Swipedatetime]) <=18
For the diff you can use this:
select DATEDIFF(minute, MIN([Swipedatetime]), MAX([Swipedatetime]))
So full query:
declare #StartDate datetime = dateadd(HH, 6, convert(datetime, convert(date, getdate())))
declare #EndDate datetime = dateadd(day,1,#Startdate)
SELECT MIN([Swipedatetime]) AS [Entry]
, MAX([Swipedatetime]) AS [Exit]
, DATEDIFF(minute, MIN([Swipedatetime]), MAX([Swipedatetime])) AS[Diff]
, [UserID]
FROM [Database_Name].[dbo].[Table_Name]
where UserID = '100'
and [Swipedatetime] >= #Startdate
and [Swipedatetime] < #EndDate
GROUP
BY UserID
, CAST (Swipedatetime as DATE)
ORDER
BY MIN([Swipedatetime])

How can I obtain only MSSQL rows that have been created since Jan 1st?

I have a script that writes database information to a csv based on a SQL query I wrote. I was recently tasked with modifying the query to return only rows where the DateTime field has a date that is newer then Jan. 1 of this year. The following query does not work:
$startdate = "01/01/2013 00:00:00"
SELECT Ticket, Description, DateTime
FROM [table]
WHERE ((Select CONVERT (VARCHAR(10), DateTime,105) as [DD-MM-YYYY])>=(Select CONVERT (VARCHAR(10), $startdate,105) as [DD-MM-YYYY]))"
The format of the DateTime field in the database is in the same format as the $startdate variable. What am I doing wrong? Is my query incorrectly formated? Thanks.
DECLARE #startdate datetime
SELECT #startdate = '01/01/2013'
SELECT Ticket, Description, DateTime
FROM [table]
WHERE DateTime >= #startdate
you can get year based records through DATEDIFF
DECLARE #startdate datetime = '01/01/2013';
SELECT Ticket, Description, DateTime
FROM [table]
WHERE DATEDIFF(YEAR,#startdate,DateTime) = 0 //It gives 0 if years are the same and DateTime is your column
You can get the start of the current year using:
DateAdd( year, Year( GetDate() ) - 1900, 0 )
The query then becomes:
select Ticket, Description, [DateTime]
from [Table]
where [DateTime] >= DateAdd( year, Year( GetDate() ) - 1900, 0 )
If you really don't want rows from January first then change the comparison from >= to >.
DECLARE #startdate datetime
SELECT #startdate = '01/01/2013'
SELECT Ticket, Description, DateTime
FROM [table]
WHERE DateTime >= #startdate
Interesting question that says as much about interpreting the requirement as about the SQL. When next year comes you will want to select next year's tickets. So it should be
SELECT Ticket, Description, DateTime
FROM [table]
WHERE datePart(yy,DateTime)=datePart(yy,getDate())
DECLARE #startdate datetime = '01/01/2013';
SELECT Ticket, Description, DateTime
FROM [table]
WHERE DATEDIFF(DD,#startdate,DateTime) >= 0

SQL query to find available future dates except weekends

I have table called "detail" where i am storing start date and end date of jobs.I have one more table called "leaves" which is also have leave startdate and leave enddate fields.I need to find the nearest available dates of a user without weekends and leave dates.
DECLARE #PackagerLastAssignedDate DATETIME
SELECT #PackagerLastAssignedDate = MAX(EndDate) FROM detail WHERE userId = 1
SELECT lveStartDate,lveEndDate FROM Leaves WHERE UserId = 1 and lveStartDate > #PackagerLastAssignedDate
Thanks In advance
Berlin.M
Try this one -
DECLARE
#DateFrom DATETIME
, #DateTo DATETIME
SELECT
#DateFrom = '20130101'
, #DateTo = '20130202'
SELECT [Date]
FROM (
SELECT [Date] = DATEADD(DAY, sv.number, t.DateFrom)
FROM (
SELECT
DateFrom = #DateFrom
, diff = DATEDIFF(DAY, #DateFrom, #DateTo)
) t
JOIN [master].dbo.spt_values sv ON sv.number <= diff
WHERE sv.[type] = 'p'
) t2
WHERE DATENAME(WEEKDAY, [Date]) NOT IN ('Saturday', 'Sunday')
AND NOT EXISTS (
SELECT 1
FROM dbo.Leaves l
WHERE l.UserId = 1
AND t2.[Date] BETWEEN l.lveStartDate AND l.lveEndDate
)