query to fetch records between two date and time - postgresql

I have been using postgreSQL. My table has 3 columns date, time and userId. I have to find out records between the given date and time frame. Since date and time columns are different, 'BETWEEN' clause is not providing valid results

Combine the two columns into a single timestamp by adding the time to the date:
select *
from some_table
where date_column + time_column
between timestamp '2017-06-14 17:30:00' and timestamp '2017-06-19 08:26:00';
Note that this will not use an index on date_column or time_column. You would need to create an index on that expression. Or better: use a single column defined as timestamp instead.

Related

PostgreSQL function lags when passing a date from another table as argument

I created a function that retrieves data from multiple table and insert the result into a new table. I am passing few dates in the where clause to filter the applicable information. The dates are in timestamptz format. The query takes roughly a min to process. However when I make the change in the where clause to pass the date from another table, the query lags a lot. i.e.
My initial argument that doesn't lag is
where timestamp = '2022-01-05 04:00:00+00'
The lag is when I change this where clause to pass this date from another table.
where timestamp = select date_time from table_Test
The date_time in table_test is defined as timestamptz and the value is '2022-01-05 04:00:00+00'.
Any idea why the query lags when I pass the date argument from another table?
Thanks,

Postgres combining date and time fields, is this efficient

I am selecting rows based on a date range which is held in a string using the below SQL which works but is this a efficient way of doing it. As you can see the date and time is held in different fields. From my memory or doing Oracle work as soon as you put a function around a attribute it cant use indexes.
select *
from events
where venue_id = '2'
and EXTRACT(EPOCH FROM (start_date + start_time))
between EXTRACT(EPOCH FROM ('2017-09-01 00:00')::timestamp)
and EXTRACT(EPOCH FROM ('2017-09-30 00:00')::timestamp)
So is there a way of doing this that can use indexes?
Preface: Since your query is limited to a single venue_id, both examples below create a compound index with venue_id first.
If you want an index for improving that query, you can create an expression index:
CREATE INDEX events_start_idx
ON events (venue_id, (EXTRACT(EPOCH FROM (start_date + start_time))));
If you don't want a dedicated function index, you can create a normal index on the start_date column, and add extra logic to use the index. The index will then limit access plan to date range, and fringe records with wrong time of day on first and last dates are filtered out.
In the following, I'm also eliminating the unnecessary extraction of epoch.
CREATE INDEX events_venue_start
ON events (venue_id, start_date);
SELECT *
FROM events
WHERE venue_id = '2'
AND start_date BETWEEN '2017-09-01'::date AND '2017-09-30'::date
AND start_date + start_time BETWEEN '2017-09-01 00:00'::timestamp
AND '2017-09-30 00:00'::timestamp
The first two parts of the WHERE clause will use the index to full benefit. the last part is then use the filter the records found by the index.

How do I convert timestamp and offset columns to a single timestamptz column?

Image I have a table containing the following two columns:
timestampwithouttimezone (of type TIMESTAMP WITHOUT TIME ZONE)
utcoffset (of type INTEGER)
I want to convert those two column to a single one of type TIMESTAMP WITH TIME ZONE. Can this be achieved using a ALTER TABLE ALTER COLUMN [column] SET DATE TYPE TIMESTAMP WITH TIME ZONE query and the additional USING clause?
Or do I need a separate UPDATE query that takes the offset and sets the timezone of the timestamps? If that's the case, what would that query be? I can't find any examples that show how to update the timezone using an integer.
You could do that like this, assuming the offset is in hours:
ALTER TABLE mytab
ALTER timestampwithouttimezone
TYPE timestamp with time zone
USING CAST (timestampwithouttimezone::text || ' '
|| to_char(utcoffset, 'S00FM')
AS timestamp with time zone),
DROP utcoffset;

PostgreSQL - aggregating data by date from datetime field

I have data over time for particular users and timestamp of the form 2013-11-23 16:00:00-05 - there's by minute by minute date for each user and corresponding usage value.
So the table has values: user_ID, localminute, usage.
I am trying to aggregate usage at a day wise level, what i did so far is below s but I was looking for an easier way to do it without creating the dummy column date_event:
alter table tablename add column date_event date
update table set date_event = date(localminute)
select sum(use), date_event from tablename group by date_event
My question is about how I can extract date from timestamp and aggregate in a single query. Thanks for any help!
Just cast it to a date:
select sum(use), localminute::date
from tablename
group by localminute::date;
or using standard SQL:
select sum(use), cast(localminute as date)
from tablename
group by cast(localminute as date);

getting second difference with sql statement

I have a table in postgresql which stores time stamp with timezone for every row inserted.
How can I use postgresql's function to find a the difference in seconds from the timestamp in one of the rows already inserted to the current postgresql server time stamp?
Assuming that the column name is ts and the table name is t, you can query like this:
select current_timestamp - max(ts) from t;
If the table contains large amount of data, this query will be very slow. In that case, you should have index on the timestamp column.