How to query between 2 specific hours of the day - postgresql

Need to query only results from a table where a specific time is only between 10:00am EST and 09:59pm EST.
Using this query example:
SELECT
s.id as "ID",
to_char(s.started_at AT TIME zone 'UTC-5', 'HH12:MIam') as "Start_time",
FROM
stats s
WHERE
s.started_at IS NOT NULL
Does anyone have a WHERE statement that would show those results regardless of DATE?

Cast the column to time:
SELECT ...
FROM states s
WHERE CAST ((s.started_at AT TIME ZONE 'EST') AS time)
BETWEEN TIME '10:00' AND TIME '21:59';

Related

TIMESTAMP- creation_date :: date between '2022-05-15' and '2022-06-15'

I just wanted to know the difference between these two codes:
select count (user_id) from tb_users where
creation_date :: date between '2022-05-15' and '2022-06-15'
Result: 41,232
select count (user_id) from tb_users where
creation_date between '2022-05-15' and '2022-06-15'
Result: 40,130
As far as I see, it is related with the timestamp, but I do not understand the difference.
Thank you!
Your column creation_date in the table is most probably in timestamp format, which is '2022-05-15 00:00:00'. By adding ::date <- you are casting your timestamp format to date format: '2022-05-15'.
You can read more about casting data types here:
https://www.postgresqltutorial.com/postgresql-tutorial/postgresql-cast/
When you ask Postgres to implicitly coerce a DATE value to a TIMESTAMP value - the hours, minutes and seconds are set to zero.
In the first query, you explicitly cast the creation date to DATE which is successfully compared to the provided DATE values.
In the second query, the creation date is of type TIMESTAMP and so PostgreSQL converts your DATE values to TIMESTAMP values and the comparison becomes
creation_date >= '2022-05-15 00:00:00' AND creation_date <= '2022-06-15 00:00:00'
Obviously, this produces different resultset than the first query.

Converting GMT to CST in postgresql

I am currently working with raw data that have timestamps in GMT and I want to convert them to CST. I am trying to use the cast function to change the timestamp, but it is not working- the times are not affected. Most of what I have read about timezones in postgresql assumes that the default timezone is UTC so I'm not sure if there is a different syntax needed for when the data I'm trying to convert is GMT. Any help is greatly appreciated!
WITH RECURSIVE "child" AS (
SELECT "ConsultantDisplayID",
"JoinDate",
"ParentPersonDisplayID"
FROM "public"."flight_export_consultant"
WHERE "ConsultantDisplayID" = '4019'
UNION
SELECT c."ConsultantDisplayID",
CAST(c."JoinDate" at time zone 'america/chicago' as timestamp) as "JoinDate"
c."ParentPersonDisplayID"
FROM "public"."flight_export_consultant" AS c
JOIN "child" AS cd
ON c."ParentPersonDisplayID" = cd."ConsultantDisplayID"),
"sponsor" AS (
SELECT
"child".*,
c1."ConsultantDisplayID",
Cast(c."JoinDate" at time zone 'america/chicago' as timestamp) as "Sponsor JoinDate"
FROM "public"."flight_export_consultant" AS c1
LEFT JOIN "child"
ON c1."ConsultantDisplayID" = "child"."ParentPersonDisplayID")
SELECT * FROM "sponsor"
As #Mike Organek pointed out a field of type timestamp assumes local time on entry. So first thing you need to establish is where the dates are being entered from and whether they are are actually being entered as GMT. For the moment assuming they are you could do the following:
select 'September 24, 2018, 4:01PM'::timestamp at time zone 'utc' at time zone 'america/chicago';
timezone
---------------------
09/24/2018 11:01:00
-- Or if you want to stick to GMT
select 'September 24, 2018, 4:01PM'::timestamp at time zone 'gmt' at time zone 'america/chicago';
timezone
---------------------
09/24/2018 11:01:00
Basically you are 'anchoring' the timestamp at UTC/GMT and then converting to 'america/chicago'. In other words replicating what a timestamptz field does.
Given that JoinDate is type timestamp, this should be a good workaround for your situation now that we have established that the values in JoinDate of type timestamp represent UTC/GMT timestamps, and your server is not in UTC/GMT. The ideal solution is to use timestamptz columns.
The trick here is to cast JoinDate to text, append a z to it to make it UTC, and then cast it to timestamptz. Once that is done, you can use at time zone 'us/chicago' to do the conversion for you.
WITH RECURSIVE "child" AS (
SELECT "ConsultantDisplayID",
"JoinDate",
"ParentPersonDisplayID"
FROM "public"."flight_export_consultant"
WHERE "ConsultantDisplayID" = '4019'
UNION
SELECT c."ConsultantDisplayID",
"JoinDate",
c."ParentPersonDisplayID"
FROM "public"."flight_export_consultant" AS c
JOIN "child" AS cd
ON c."ParentPersonDisplayID" = cd."ConsultantDisplayID"),
"sponsor" AS (
SELECT
"child".*,
c1."ConsultantDisplayID",
c."JoinDate" as "Sponsor JoinDate"
FROM "public"."flight_export_consultant" AS c1
LEFT JOIN "child"
ON c1."ConsultantDisplayID" = "child"."ParentPersonDisplayID")
SELECT "ConsultantDisplayID",
("JoinDate"::text||'z')::timestamptz at 'america/chicago' as "JoinDate",
"ParentPersonDisplayID",
"ConsultantDisplayID",
("JoinDate"::text||'z')::timestamptz at 'america/chicago' as "Sponsor JoinDate"
FROM "sponsor";

How to handle timestamp with timezone on postgres with knex.js

I am trying to translate following sql query into knex:
select count(*) as finished_on_time from task_history
where date = 20160303
and store_id = 2
and (schedule_start_time at time zone 'Australia/sydney' + interval '1' minute * floor (group_duration) )::time >= (finish_time at time zone 'Australia/sydney')::time
date field has in yyyymmdd format
Here is what I have been trying on knex:
db.table('task_history')
.count('*')
.where({date: request.params.storeid, store_id: request.params.storeid })
??????
As you can guess, I am not sure which clause to use to handle sql syntax [at time zone Australia/sydney].
I have been trying to find any similar soloutions on the internet, but ended up here.
http://knexjs.org/#Builder-whereRaw
db.table('task_history')
.count('*')
.where({date: request.params.storeid, store_id: request.params.storeid })
.whereRaw("(schedule_start_time at time zone 'Australia/sydney' + interval '1' minute * floor (group_duration) )::time >= (finish_time at time zone 'Australia/sydney')::time")

SUM Data if Duplicate in Postgres

I am having table with three columns and may have duplicate data in it. what I am trying to do is if BATCH Column is having Duplicate Data then START_S and END_S should be according to below Example
CREATE TABLE "DRL_FTO3_DI1_A0_BATCH"
(
"BATCH" character varying(128),
"START_S" integer,
"END_S" integer
)
INSERT INTO "DRL_FTO3_DI1_A0_BATCH"(
"BATCH", "START_S", "END_S")
VALUES ('Batch 1_1',1451120920,1451121008),
('Batch 01_2',1451389014,1451389100),
('Batch 2_1',1451534680,1451534918),
('Batch 3_1',1451539145,1451539264),
('Parth_2',1451540990,1451541285),
('Parth_2',1451541676,1451542254)
SELECT "BATCH",((TIMESTAMP WITHOUT Time Zone 'epoch' + "START_S" * INTERVAL '1 second') AT TIME ZONE 'UTC')::TIMESTAMP WITHOUT Time Zone,
((TIMESTAMP WITHOUT Time Zone 'epoch' + "END_S" * INTERVAL '1 second') AT TIME ZONE 'UTC')::TIMESTAMP WITHOUT Time Zone
FROM "DRL_FTO3_DI1_A0_BATCH"
Now as we can see Parth_2 is duplicate value so START_S and END_S for Parth_S should be
Parth_2 2015-12-31 11:19:50 2015-12-31 11:40:54
You could do it using GROUP BY and MIN/MAX aggregate functions (you can convert into date time later with below query in format you desire) like:
SELECT BATCH, MIN(START_S), MAX(END_S)
FROM DRL_FTO3_DI1_A0_BATCH
GROUP BY BATCH

problems to get the full DATE info from Oracle DB (dd/mm/yyyy hh/mm/ss)

I have a column in a table in which we are storing date in DATETIME format. (DD-MON-RRRR HH24:MI:SS) - Database Oracle 11g.
Data Type of a column is DATE, and storing date in 01-01-2012 01:00 PM (i.e. jan 1, 2012) format.
entity
#NotNull
#Column(name = "dateColumnName")
#Temporal(TemporalType.TIMESTAMP)
private Date sampleDate;
I am fetching all data by passing date
SAMPLE_QUERY = "select * from TableA tab where tab.dateWithTime = :sampleDate order by tab.dateWithTime ASC "
singleDate is "Tue Jan 24 00:00:00 IST 2012" , fasttime :
1327343400000
The problem is I am passing only date in the query, though Date through which records are being fetched is in DATE TIME format i.e 01-01-2012 01:00 PM.
How can i change my query so that it fetches all the records in ascending order of DateTime.
If you want to fetch all times for that day, then change your query to be more like
SELECT ... WHERE dateField >= :lowerParam AND dateField < :upperParam
Oracle has no DATE TIME datatype. The DATE datatype contains both a date and a time component, down to the second. TIMESTAMPS get a bit more complicated.
If your dateWithTime column is indeed a DATE datatype, the ORDER BY dateWithTime ASC clause should order your results in ascending order.
You may not be displaying the time component of your date. You can convert a date to a string in that format with TO_CHAR( dateWithTime, 'dd/mm/yyyy hh24/mm/ss' ) or whatever format you want.
Edit:
Oh, do you mean you want to find the cases where the date component of the DATE matches, but you don't care about the time component? That can be handled in the where clause with something like:
WHERE TRUNC( tab.dateWithTime ) = TRUNC( :sampledate )
TRUNC by default truncates a date to the beginning of the day.