Get rows in between hours with SQL - sql

I have thousands of records (rows) that contain a time column.
I can easily get rows with time's in between 4 AM and 5 AM by doing this:
SELECT * FROM MyTable
WHERE CAST(Time AS TIME) BETWEEN '04:00' and '05:00'
To get the rows between 6PM and 4AM:
SELECT * FROM MyTable
WHERE CAST(Time AS TIME) BETWEEN '18:00' and '04:00'
Gives me zero rows..
How can I do this?

Casting a time to a time is strange, but I assume it's actually a Timestamp :-)
You might also use EXTRACT:
SELECT *
FROM MyTable
WHERE EXTRACT(HOUR FROM Time) >= 18
AND EXTRACT(HOUR FROM Time) < 4

Try:
SELECT *
FROM MyTable
WHERE CAST(Time AS TIME) NOT BETWEEN '04:00' AND '18:00'
The values to between (and not between) need to be in order, with the smaller value first. Otherwise, nothing will match.
The expression:
x between a and b
is exactly equivalent to
((x >= a) and (x <= b))

Related

SQL query SELECT time intervals

I'm trying to SELECT all the rows from a SQL database which are between an hour interval, for every day.
The datetime column is called "Dt" and has the following datetime format: 2019-10-17 16:03:43
I'd like to extract all the rows from this table where the Dt was between 22:00:00 and 02:00:00, for everyday.
SELECT *
FROM MY_TABLE
WHERE "Dt" BETWEEN '*-*- 22:00:00' AND '*-*- 02:00:00';
where * should be any...
Thanks for your support!
EDIT: I forgot to mention: I'm using the integrated SQL interpreter from DB Browser for SQLite
You need to extract the time part of the date and compare that it is within the range. Since midnight is between 22 and 2, you will need to split it to two comparisons, time between 22 and 0 and between 0 and 2.
To see how to extract the time take a look at this question.
With Postgres, assuming dt is defined as timestamp you can do the following:
SELECT *
FROM MY_TABLE
WHERE "Dt" BETWEEN "Dt"::date + time '22:00:00' and ("Dt"::date + 1) + time '02:00:00'
Or if you want to exclude timestamps at precisely 02:00:00
SELECT *
FROM MY_TABLE
WHERE "Dt" >= "Dt"::date + time '22:00:00'
and "Dt" < ("Dt"::date + 1) + time '02:00:00'
select DT_time from (
select cast (substr(to_char(Dt,'dd-mm-yyyy HH:MM:SS'),12,2) as integer ) as DT_time from MY_TABLE )
where DT_time between 2 and 22;
between 22:00:00 and 02:00:00
means:
SELECT *
FROM MY_TABLE
WHERE
substr(Dt, 12) BETWEEN '22:00:00' AND '23:59:59'
OR
substr(Dt, 12) BETWEEN '00:00:00' AND '02:00:00'
This will work ::
SELECT *
FROM MY_TABLE
WHERE DATEPART(HOUR, Dt)>22
AND DATEPART(HOUR, Dt)<2
Update :
SELECT *
FROM MY_TABLE
WHERE Dt Between DATEADD (hour,22,DATEADD(day, DATEDIFF(day, 0, Dt), 0)) AND DATEADD (hour,2,DATEADD(day, DATEDIFF(day, -1, Dt), 0))
SELECT *
FROM MY_TABLE
WHERE DATEPART(HOUR, Dt)>22
OR DATEPART(HOUR, Dt)<2
Above query work for you..
1st one will check only for particular date and consecutive next date along with your time range.
But If you don't care about dates and only looking for time interval in particular hours then 2nd one is for you.
For SQLite :
SELECT *
FROM MY_TABLE
WHERE strftime('%H','Dt')>22
OR strftime('%H','Dt')<2

SUM the value based on the time and date

I need help for adding different time interval reads value for date.
Suppose in day they are 24 hours, and I want the sum of 4-8pm in one row and another i.e. 0-4pm and 9pm 12 am in one row.
I was using below query :
SELECT
ennt_date,
CASE
WHEN to_number(TO_CHAR(dta.end_time,'HH24:MI:SS'),'sssss')/60 >= 960
AND to_number(TO_CHAR(dta.end_time,'HH24:MI:SS'),'sssss') /60 <=
1200
THEN (reads)
ELSE (reads)
END
from MD_data
group by ennt_date
getting error saying:
case is not group by function
This should work. You can adjust the hhGroup time ranges per your needs. I was unclear as to whether the 4pm-8pm went thru 7:59 (8pm) or thru 8:59(9pm)
SELECT ennt_date
,hhGroup
,Count(1) as cnt
FROM
(Select
ennt_date
,CAST( dta.end_time as time) as tm
,DATEPART(HH, dta.end_time ) as hh
,CASE When DATEPART(HH, dta.end_time ) < 16 Then '0am-4pm'
When DATEPART(HH, dta.end_time ) < 20 Then '4pm-8pm'
When DATEPART(HH, dta.end_time ) < 21 Then '8pm-9pm'
When DATEPART(HH, dta.end_time ) < 24 Then '9pm-mid'
END as hhGroup
From md_data
) as mm
GROUP BY ennt_date, hhGroup
You can divide the day in 4-hour segments and sum each one separately:
with
x as (
select
(extract(hour from end_time) div 4) * 4 as fragment,
reads
from md_data
)
select
fragment,
sum(reads)
from x
group fragment
Sample results would help, but I think you want:
SELECT trunc(ennt_date),
( ceil( extract(hour from ennt_date) / 4.0) * 4 - 4 ) as hour,
SUM(reads)
from MD_data
group by trunc(ennt_date),
ceil( extract(hour from ennt_date) / 4.0);

Converting query from Microsoft SQL to Oracle

The following Microsoft SQL query compares two date fields of a table and returns those records for which the difference in minutes is greater than 5.
SELECT t.Id, t.date1, t.date2,
DATEDIFF(MINUTE, t.date1 , t.date2) AS Mtime
FROM table1 t
WHERE
DATEDIFF(MINUTE,t.date1, t.date2) > 5
I have no idea how to write this with ORACLE. I've searched for solution and the closest I came to was :
SELECT t.date1, t.date2,
(t.date1 - t.date2) * 1440 AS Mtime
FROM table1 t
WHERE
(t.date1 -t.date2) * 1440 > 5
which gives me the error inconsistent datatypes: expected INTERVAL DAY TO SECOND got NUMBER
Does anyone know how to write this query with ORACLE ?
Don't use the difference. Just add the interval:
WHERE t.DeliveryDate >= t.Deadline + interval '5' minute
Or:
WHERE t.DeliveryDate >= t.Deadline + 5 / (24 * 60)
The equivalent in SQL Server is:
WHERE t.DeliveryDate >= DATEADD(minute, 5, t.Deadline)
This is a good habit. If one of the values is a constant, then the use of a function (- or datediff()) prevents the use of an index.
This should work -
SELECT t.Id, t.date1, t.date2,
(CAST(t.date1 AS DATE)-CAST(t.date2 AS DATE)) * 1440 AS Mtime FROM table1 t where (CAST(t.date1 AS DATE)-CAST(t.date2 AS DATE)) * 1440 > 5

How to get hour by hour data in sql server (specific with minutes)

how to get hour by hour data (no matter what is the date) in sql server, I know it can be achieved with datePart(hour, columnname) but to be specific, I need data for specific intervals including minutes regardless of dates.
Scenario: 'TestTable' contains column - DBTimestamp with data type (DateTime)
I need all Records from 'TestTable' for which 'DBTimestamp' is between 3 Hours 35 Minutes And 4 Hours 30 Minutes regardless of date specified.
You can use this.
SELECT * FROM TestTable WHERE CAST(DBTimestamp AS TIME) BETWEEN '03:35' AND '04:30'
From my understanding you need records that in specific range of time regardless of date part. So I've come up with following solution:
SELECT * FROM (SELECT Id, CAST(Time AS time) [time]
FROM Table) AS Q1
WHERE Q1.time > CAST('03:35:00' AS time)
AND Q1.time < CAST('12:30:00' AS time)
Here is SQL Fiddle:
http://sqlfiddle.com/#!6/21b313/1
Well I guess you could do some variation of the following:
SELECT *
FROM TABLE
WHERE (DATEPART(HOUR, TIMESTAMP) = 3 AND DATEPART(MINUTE, TIMESTAMP) >= 35) OR
(DATEPART(HOUR, TIMESTAMP) = 4 AND DATEPART(MINUTE, TIMESTAMP) <= 30)

How can I group by date time column for custom hour

How can I group by date time column for custom hour, for example every 5 Hour or every 12 Hour or every 24 hour.
Select CreateOn, Count(*) From Table1
Group By ?????
You should select start date/time, '2011-01-01' in this example and then use DATEDIFF() function to get time difference in hours between start date and CreateOn. Then use / operator to get an integer interval number (5 hours in this example).
Select
min(DATEADD(HOUR,DATEDIFF (HOUR,'2011-01-01',CreateOn )/5*5,'2011-01-01'))
as Start_time,
max(DATEADD(HOUR,(DATEDIFF (HOUR,'2011-01-01',CreateOn )/5+1)*5,'2011-01-01'))
as End_Time,
DATEDIFF (HOUR,'2011-01-01',CreateOn )/5 as Interval_Number,
Count(*) as _Count
From Table1
Group By DATEDIFF (HOUR,'2011-01-01',CreateOn )/5
If I understand your question correctly, you could try something like this:
SELECT CreateOn, Count(*) FROM Table1 GROUP BY (DATEPART(MINUTE, [Date]) % 12)