Why the following query return false?
SELECT ('00:00:00'::TIME) = ('24:00:00'::TIME) AS "time", ('00:00:00'::TIMETZ) = ('24:00:00'::TIMETZ) AS "timetz"
Result:
+-------+--------+
| time | timetz |
+-------+--------+
| false | false |
+-------+--------+
While the result of the following query is same!!
SELECT ('00:00:00'::TIME) AS "time1", ('24:00:00'::TIME) AS "time2", ('00:00:00'::TIMETZ) AS "timetz1" , ('24:00:00'::TIMETZ) AS "timetz2"
Result:
+----------+----------+------------------------+------------------------+
| time1 | time2 | timetz1 | timetz2 |
+----------+----------+------------------------+------------------------+
| 00:00:00 | 00:00:00 | 00:00:00.000000 +00:00 | 00:00:00.000000 +00:00 |
+----------+----------+------------------------+------------------------+
What is difference between 00:00:00 and 24:00:00 in postgres?
Postgres' time type is defined to have a range of '00:00:00' to '24:00:00', inclusive on both ends. To see why the two endpoints are not the same, consider:
SELECT '00:00:00'::time AS start, '24:00:00'::time AS end;
For the end value, I see 1.00:00:00, contrary to what you see, indicating that 24 hours is actually one day, with zero hours, minutes, and seconds.
Related
I have a table that has following columns:- local_id | time_in | time_out | date | employee_id
I have to calculate average working hours(which will be calculated by time_out and time_in) on a monthly basis in PSQL. I have no clue how to do that, was thinking about using date_part function...
here are the table details:
local_id | time_in | time_out | date | employee_id
---------+----------+----------+------------+-------------
7 | 08:00:00 | 17:00:00 | 2020-02-12 | 2
6 | 08:00:00 | 17:00:00 | 2020-02-12 | 4
8 | 09:00:00 | 17:00:00 | 2020-02-12 | 3
13 | 08:05:00 | 17:00:00 | 2020-02-17 | 3
12 | 08:00:00 | 18:09:00 | 2020-02-13 | 2
Click: demo:db<>fiddle; extended example covering two months
SELECT
employee_id,
date_trunc('month', the_date) AS month, -- 1
AVG(time_out - time_in) -- 2, 3
FROM
mytable
GROUP BY employee_id, month -- 3
date_trunc() "shortens" the date to a certain date part. In that case, all dates are truncated to the month. This gives the opportunity to group by month. (for your "monthly basis")
Calculate the working time by calculating the difference of both times
Grouping by employee_id and calculated month, calculating the average of the time differences.
I have problem in sorting & querying data with timezone offset.
I have PostgreSQL + TimescaleDB where I have time series data. Target is to get daily maximums based on local time zone.
My data is in UTC but query needs to be in local timezone as my cumulative counters are resetting in local time.
Target is to have result as in below
id | time | dailymax | name
-------+---------------------+------------------+------------------------
10001 | 2020-01-05 | 0 | Property1
10002 | 2020-01-05 | 20930.3490579984 | Property2
10003 | 2020-01-05 | 28347.1322223556 | Property3
10001 | 2020-01-04 | 57872.3274949118 | Property1
10002 | 2020-01-04 | 101159.612050399 | Property2
10003 | 2020-01-04 | 34113.226521315 | Property3
10001 | 2020-01-03 | 0 | Property1
10002 | 2020-01-03 | 17386.2914203308 | Property2
10003 | 2020-01-03 | 160599.774657208 | Property3
My best guess has been so far query in below, but it gives me also records from wrong days and takes long to execute
SELECT table.id, CAST(datetime AS DATE) AT TIME ZONE 'America/New_York' as time, MAX(value) AS value, map.tagname FROM table
JOIN map ON table.id = map.id
WHERE table.id in(10003,10029,10008,10036,10007) AND datetime AT TIME ZONE 'UTC' >= '2019-12-30T16:09:32.080Z' AND datetime AT TIME ZONE 'UTC' < '2020-01-06T16:09:32.080Z'
GROUP BY table.id, map.tagname, time
ORDER BY time DESC;
With TimescaleDB tried something as in below with bad luck as well
SELECT table.id, to_char(time_bucket('24 hours', datetime) at time zone 'utc', 'YYYY-MM-DD"T"HH24:MI:SS"Z"') as time, max(value) as value, map.name FROM
table JOIN map ON table.id = map.id
WHERE table.id in(10001,10002) AND datetime >= '2020-01-01' AND datetime < '2020-01-10'
GROUP BY time, table.id, map.name ORDER BY time DESC`;
I have the following table with epoch timestamps in Postgres. I would like to select the timestamps where the time is from 20:00 to 21:00 in PST. I have tried the following partially but I can't seem to extract both hour and minutes.
SELECT timestamp from table where extract(‘hour’ from to_timestamp(created_at) at time zone ‘America/Los_angeles’) > 20
| created_at |
| 1526528788 |
| 1526442388 |
| 1526309188 |
| 1526359588 |
| 1526532388 |
| 1526489188 |
Expected result:
| created_at |
| 1526528788 |
| 1526442388 |
Any help would be greatly appreciated.
Why do you write America/Los Angeles when you mean PST? They are (sometimes) different.
Does that solve your problem:
... WHERE extract(hour FROM
to_timestamp(1526309188) AT TIME ZONE 'PST'
) BETWEEN 20 AND 21;
I'm using PostgreSQL and this is my table measurement_archive:
+-----------+------------------------+------+-------+
| sensor_id | time | type | value |
+-----------+------------------------+------+-------+
| 123 | 2017-11-26 01:53:11+00 | PM25 | 34.32 |
+-----------+------------------------+------+-------+
| 123 | 2017-11-26 02:15:11+00 | PM25 | 32.1 |
+-----------+------------------------+------+-------+
| 123 | 2017-11-26 04:32:11+00 | PM25 | 75.3 |
+-----------+------------------------+------+-------+
I need a query that will take records from specified timeframe (eg. from 2017-01-01 00:00:00 to 2017-12-01 23:59:59) and then check if in every hour there is at least 1 record - if there is, then add 1 to result.
So, if I make that query from 2017-11-26 01:00:00 to 2017-11-26 04:59:59+00 for sensor_id == 123 on above table then the result should be 3.
select count(*)
from (
select date_trunc('hour', time) as time
from measurement_archive
where
time >= '2017-11-26 01:00:00' and time < '2017-11-26 05:00:00'
and
sensor_id = 123
group by 1
) s
alternative solution would be using distinct,
select count(*) from (select distinct a, extract(hour from time) from t where time >'2017-11-26 01:00:11' and time <'2017-11-26 05:00:00' and sensor_id=123)t;
I have the folowing table:
| id | duty_id | date_start | date_end |
| 1 | 1 | 2015-07-16 07:00:00 | 2015-07-16 14:30:00 |
| 2 | 3 | 2015-07-17 03:30:00 | 2015-07-17 11:00:00 |
| 3 | 5 | 2015-07-17 12:00:00 | 2015-07-17 19:30:00 |
and i have a date: 2015-07-17.
and i need to select the rows that happens on my date. AKA i need these lines:
| 2 | 3 | 2015-07-17 03:30:00 | 2015-07-17 11:00:00 |
| 3 | 5 | 2015-07-17 12:00:00 | 2015-07-17 19:30:00 |
sadly the BETWEEN doesn't work:
SELECT * FROM table WHERE ('2015-07-17'::DATE BETWEEN date_start AND date_end)
gives back empty result.
How can i get those lines?
The problem is that when a DATE is coerced to a TIMESTAMP (as must be done here to compare the DATE of '2015-07-17' to the TIMESTAMPs in the data) the time portion of the coerced TIMESTAMP is set to 00:00:00, and thus since the test data doesn't have a time period which is valid at midnight on 2015-07-17 no rows are returned.
If you add an INTERVAL literal of 211 minutes (three hours and 31 minutes) to the converted date you'll get results returned because the test data DOES have a row which is valid at 2015-07-17 at 03:31 AM:
SELECT * FROM my_table
WHERE '2015-07-17'::DATE + INTERVAL '211' MINUTE BETWEEN date_start
AND date_end;
SQLFiddle here
Best of luck.
Please try something like this:
SELECT * FROM table
WHERE '2015-07-17'::DATE BETWEEN date_start::DATE AND date_end::DATE;
SQLFiddle excample