How can I find the data between two specific times in SQL - sql

I need to run a query that finds all login dates (dd/mm/yyyy) and times (hh.mm) that occurred between 2am yesterday and 2am today. The login time in the database is formatted as mm-dd-yyyy hh.mm.ss.
I have tried multiple select and between queries that either return data on the wrong day or outside the time spans.

Based on the information that you provided, I can only give a generic example:
SELECT *
FROM [YourTable]
WHERE [YourDate] BETWEEN '08-15-2011 02:00:00' AND '08-16-2011 02:00:00'
**EDIT**
Per a good suggestion from the comments, here is a reusable version:
SELECT *
FROM [YourTable]
WHERE [YourDate] BETWEEN DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0) + '02:00'
AND DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()-1), 0) + '02:00'

Assuming mysql:
SELECT * FROM your_table
WHERE STR_TO_DATE(your_date, '%m-%d-%Y %H.%i.%s') BETWEEN
DATE_SUB(STR_TO_DATE(DATE_FORMAT(NOW(), '%m-%d-%Y'), '%m-%d-%Y'), INTERVAL 22 HOUR) AND
DATE_ADD(STR_TO_DATE(DATE_FORMAT(NOW(), '%m-%d-%Y'), '%m-%d-%Y'), INTERVAL 2 HOUR)
I'm sure there's a better way though.

The query doesn't return any records if we use as follows...
SELECT *
FROM [YourTable]
WHERE [YourDate] BETWEEN DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0) + '02:00'
AND DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()-1), 0) + '02:00'
We are using between clause so the oldest date should be first and the query becomes as follows...
SELECT *
FROM [YourTable]
WHERE [YourDate] BETWEEN DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()-1), 0) + '02:00'
AND DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0) + '02:00'

This can also help you out
where pt.status in (1)
and pt.is_visible in ('t')
and pt.merchant in (0)
and (date(pt.created_at+'05:30') >= current_date-2
and extract(hour from(pt.created_at+'05:30')) >=17)
and ((pt.created_at+'05:30') <= current_date-1
and extract(hour from(pt.created_at+'05:30')) <=17)

I think you can use these tips :
SET #start = CURDATE() - interval 1 DAY + interval 2 HOUR;
SET #end = CURDATE() + interval 2 HOUR;
And :
SELECT * FROM TABLE_NAME WHERE DATE_FIELD BETWEEN #start AND #end

Related

SQL, get any data between two days and specific time

I am trying to get any data that is between that time range of two days ago until yesterday.
Example: Retrieve any data between 3 PM two days ago and yesterday 3 PM. This query should work on the daily basis.
I am thinking something like but just don't know where to insert the time
select * from dbo.table where system_date between getdate()-2 and getdate()-1
You can use CAST(CAST(GETDATE() AS date) AS datetime) to get the beginning of today's date, then use DATEADD to subtract 1 or 2 days, and add 15 hours.
I strongly suggest you use >= AND < on dates, rather than BETWEEN, otherwise you get "on the interval" issues.
SELECT t.*
FROM dbo.[table] t
WHERE t.system_date >= DATEADD(hour, 15, DATEADD(day, -2, CAST(CAST(GETDATE() AS date) AS datetime)))
AND t.system_date < DATEADD(hour, 15, DATEADD(day, -1, CAST(CAST(GETDATE() AS date) AS datetime)));
try this
select *
from dbo.table
where system_date between dateadd(day, datediff(day, 2, getdate()), '15:00:00') and dateadd(day, datediff(day, 1, getdate()), '15:00:00')
You should use DATEADD for subtracting dates. Your query will look like this.
select *
from table
where system_date between dateadd(day, -2, getdate()) and dateadd(day, -1, getdate())

SQL Code to Pull data from previous day 4am up to 3:59am current day

I am trying to pull all data for the previous day starting from 4am until 3:59am CST of the current day.
For example:
Today is 11/4/20 so I would want all data from 11/3/2020 04:00 - 11/4/2020 03:59
Can somebody help me with this? I feel like I am over thinking this and can't figure it out!
SELECT
[auth_account_number] as [Employeee ID]
,'Pearl Card Withdraw $' as [Time Off]
,tm.updated_date_time as [Date]
,[payment_amount] as [Total Time]
FROM [ig_business].[dbo].[Check_GA_Account_Charge_Detail] cd
inner join [ig_transaction].[dbo].[Transaction_Master] tm on cd.transaction_data_id=tm.transaction_data_id
where tender_dim_id='104'
and tm.updated_date_time >= convert(datetime, dateadd(day, 1, convert(date, getdate()))) + '04:00:00'
and tm.updated_date_time < convert(datetime, convert(date, getdate())) + '04:00:00'
Assuming you have a date/time column, you can use:
select t.*
from t
where dt >= convert(datetime, dateadd(day, -1, convert(date, getdate()))) + '04:00:00' and
dt < convert(datetime, convert(date, getdate())) + '04:00:00'
I was able to figure it out I used this code
and tm.updated_date_time <= dateadd(day, datediff(day, 0, getdate()), 0) + '4:00'
and tm.updated_date_time > dateadd(day, datediff(day, 0, getdate()-1), 0) + '4:00'

Not another SQL time between dates minus weekends question

I have two dates: CREATION_DATE and START_DATE. START_DATE will always be later than CREATION_DATE. I need to calculate the number of minutes between them, except for minutes which happen on a weekend.
Every solution I can find assumes one of those dates occurs on a weekend, but alas, if CREATION_DATE is on a Friday, and START_DATE is a Monday, all of Saturday and Sunday is counted.
I've even tried calculating minutes from CREATION_DATE to the next 12am occurs plus minutes from first 12am Monday to START_DATE, but that doesn't work either.
I have found a solution if I only wanted to count days. I need to know down to minutes.
Our DB is hosted an I am not able to create VB functions so my solution must be all SQL.
The basic idea is to generate a record for all minutes between the start and finish, including those on weekends. Then use the WHERE clause to filter out those you don't want. In many cases, this is done by joining to a Calendar table, so you can also look at holidays or other special events, but for this purpose we can just use the DATEPART() function.
One this is done, we use a GROUP BY to roll things back up to the original date values and the COUNT() function to know how much work we did.
This basic concept works whether you're counting days, minutes, months, whatever.
It's not clear in the question, but I'm gonna assume your start and end values are columns in a table, rather than variable names (no #).
WITH Numbers(Number) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY s1.[object_id]) - 1
FROM sys.all_columns AS s1
CROSS JOIN sys.all_columns AS s2
)
SELECT t.CREATION_DATE, t.START_DATE, COUNT(*) AS Num_Minutes
FROM [MyTable] t
INNER JOIN Numbers n on n.Number <= DATEDIFF(minute, t.CREATION_DATE, t.START_DATE)
WHERE DATEPART(dw, DATEADD(minute, n.Number, t.CREATION_DATE)) NOT IN (7,1)
GROUP BY t.CREATION_DATE, t.START_DATE
But this has the potential to be very slow, depending on how far apart the dates are. You can improve this by using various other ways to generate the Numbers table to get a starting point that better approximates the needs of your actual data.
If you aren't worried about accounting for holidays, you can do this as a simple math problem without having to monkey around with a tally table or doing any counting.
The following works by dropping the time portion off the begin and end date parameters and calculates the number of working days from that and multiples that figure by 3660. From there, if the begin date is a week day the begin date mins are subtracted... if end date is a weekday, those mins are added.
DECLARE
#BegDate DATETIME = '2018-09-13 03:30:30',
#EndDate DATETIME = '2018-09-18 03:35:27';
SELECT
working_mins = bm.base_mins
- ((1 - (x.is_beg_sat + x.is_beg_sun)) * x.beg_mins) -- if the begin date is a week day, subtract the mins from midnight.
+ ((1 - (x.is_end_sat + x.is_end_sun)) * x.end_mins) -- if the end date is a week day add the mins from midnight.
--,*
FROM
( VALUES (
DATEADD(DAY, DATEDIFF(DAY, 0, #BegDate), 0),
DATEADD(DAY, DATEDIFF(DAY, 0, #EndDate), 0)
) ) d (beg_date, end_date)
CROSS APPLY ( VALUES (
DATEDIFF(MINUTE, d.beg_date, #BegDate),
DATEDIFF(MINUTE, d.end_date, #EndDate),
DATEDIFF(DAY, d.beg_date, d.end_date),
DATEDIFF(WEEK, d.beg_date, d.end_date) * 2,
1 - SIGN(DATEPART(WEEKDAY, d.beg_date) % 7),
1 - SIGN(DATEPART(WEEKDAY, d.end_date) % 7),
1 - SIGN((DATEPART(WEEKDAY, d.beg_date) + 7) % 8),
1 - SIGN((DATEPART(WEEKDAY, d.end_date) + 7) % 8)
) ) x (beg_mins, end_mins, total_days, weekend_days, is_beg_sat, is_end_sat, is_beg_sun, is_end_sun)
CROSS APPLY ( VALUES (1440 * (x.total_days - x.weekend_days + x.is_beg_sat - x.is_end_sat)) ) bm (base_mins);
You can take a look at this solution, and see if meets your needs. Basically, I did the following:
Take the number of whole days betwen StartDate and EndDate that aren't weekend days, and multiply by 2:
SELECT COUNT(*) * 24 * 60 FROM WholeDaysBetween WHERE wkday <= 5
Take the minutes from StartDate (hours*60 + minutes)
(24 * 60) - (DATEPART(HOUR, #StartDate) * 60) - (DATEPART(MINUTE, #StartDate))
Take the minutes from EndDate (hours*60 + minutes)
(DATEPART(HOUR, #EndDate) * 60) + (DATEPART(MINUTE, #EndDate))
To get the number of whole days between, I used a recursive CTE:
WITH
WholeDaysBetween(dt, wkday) AS
(
SELECT DATEADD(DAY, 1, #StartDate), DATEPART(WEEKDAY, DATEADD(DAY, 1, #StartDate))
UNION ALL
SELECT DATEADD(DAY, 1, dt), DATEPART(WEEKDAY, DATEADD(DAY, 1, dt))
FROM WholeDaysBetween
WHERE dt < DATEADD(DAY, -1, #EndDate)
)
Of course, for this to work, you have to adjust your datefirst settings.
The final query is as follows (I used the same sample data as in your comment):
set datefirst 1; -- day starts on Monday
declare #StartDate datetime = '2018-09-21 23:59:00';
declare #EndDate datetime = '2018-09-24 00:01:00';
WITH
WholeDaysBetween(dt, wkday) AS
(
SELECT DATEADD(DAY, 1, #StartDate), DATEPART(WEEKDAY, DATEADD(DAY, 1, #StartDate))
UNION ALL
SELECT DATEADD(DAY, 1, dt), DATEPART(WEEKDAY, DATEADD(DAY, 1, dt))
FROM WholeDaysBetween
WHERE dt < DATEADD(DAY, -1, #EndDate)
)
SELECT
-- whole weekdays between #StartDate and #EndDate,
-- multiplied by minutes per day
(
SELECT COUNT(*) * 24 * 60
FROM WholeDaysBetween
WHERE wkday <= 5
)
+
-- minutes from #StartDate date to end of #StartDate
-- as long as #StartDate isn't on weekend
(
SELECT
CASE
WHEN DATEPART(WEEKDAY, #StartDate) <= 5
THEN
(24 * 60) -
(DATEPART(HOUR, #StartDate) * 60) -
(DATEPART(MINUTE, #StartDate))
ELSE 0
END
)
+
-- minutes from start of #EndDate's date to #EndDate
-- as long as #EndDate isn't on weekend
(
SELECT
CASE
WHEN DATEPART(WEEKDAY, #EndDate) <= 5
THEN
(DATEPART(HOUR, #EndDate) * 60) +
(DATEPART(MINUTE, #EndDate))
ELSE 0
END
)

Sybase - Filter records with current date efficiently

I am trying to filter records based on current date (date part only) against a column "date_sent" which is a DateTime datatype. Though this can be written in multiple ways, I want to know which method will be the most efficient. The table has 11-12 millions of records ant any given time.
Let's say the current date is 16th April 2018
SELECT *
FROM TABLE_NAME
WHERE datepart(YEAR, date_sent) = 2018
AND datepart(MONTH,date_sent) = 4
AND datepart(DAY,date_sent) = 16;
SELECT *
FROM TABLE_NAME
WHERE convert(char(8), date_sent, 112) = convert(char(8), getdate(), 112);
Any other suggestions.
I would start with:
select *
from table_name
where date_sent >= dateadd(day, datediff(day, 0, getdate()), 0) and
date_sent < dateadd(day, 1 + datediff(day, 0, getdate()), 0)
The right hand side removes the time component of the current date. The comparisons should allow Sybase to still us an index on date_sent.
EDIT:
Perhaps Sybase doesn't permit 0 as a date value. You can also do:
select *
from table_name
where date_sent >= dateadd(day, datediff(day, cast('2000-01-01' as date), getdate()), cast('2000-01-01' as date)) and
date_sent < dateadd(day, 1 + datediff(day, cast('2000-01-01' as date), getdate()), cast('2000-01-01' as date))

how to get records of previous day using tsql?

I need all the records from last day?
Hi
Select * from table1 where tabledate > getdate() -1
with this query, i need to run is exactly after midnight to get exact result. I need to run it in day time and get all the previous day's records.
In SQL Server 2005, this is generally the fastest way to convert a datetime to a date:
DATEADD(day, DATEDIFF(day, 0, yourDate), 0)
In your case, it's done only once, so the how doesn't really matter much. But it does give the following query.
Select
*
from
table1
where
tabledate >= DATEADD(day, DATEDIFF(day, 0, getDate()) - 1, 0)
AND tabledate < DATEADD(day, DATEDIFF(day, 0, getDate()), 0)
Check this page out. It is a great resource for calculating dates.
http://www.simple-talk.com/sql/learn-sql-server/robyn-pages-sql-server-datetime-workbench/#calculatingdates
Another method is to use DATEDIFF alone:
SELECT * FROM table1
WHERE DATEDIFF(DAY, tabledate, GETDATE()) = 1
A datediff of 1 for day covers any time in the previous day.
DECLARE #d SMALLDATETIME;
SET #d = DATEDIFF(DAY, 0, GETDATE());
SELECT <cols> FROM dbo.table1
WHERE tabledate >= DATEADD(DAY, -1, d)
AND tabledate < #d;
Try this:
your_field = cast(dateadd(D,-1,getdate()) as DATE)