Postgres where clause compare timestamp - postgresql

I have a table where column is of datatype timestamp
Which contains records multiple records for a day
I want to select all rows corresponding to day
How do I do it?

Assuming you actually mean timestamp because there is no datetime in Postgres
Cast the timestamp column to a date, that will remove the time part:
select *
from the_table
where the_timestamp_column::date = date '2015-07-15';
This will return all rows from July, 15th.
Note that the above will not use an index on the_timestamp_column. If performance is critical, you need to either create an index on that expression or use a range condition:
select *
from the_table
where the_timestamp_column >= timestamp '2015-07-15 00:00:00'
and the_timestamp_column < timestamp '2015-07-16 00:00:00';

Related

Create date column from year and doy column

Is there a way to create a date column combining one column having the year as string and one column containing a date-of-year (doy) as integer?
I am aware of methods like SELECT EXTRACT(DOW FROM TIMESTAMP '2001-02-16 20:38:40'); or SELECT to_char(date_trunc('year', now()) + interval '169 days', 'MM/DD') but when trying to replace the "hard coded" stings with the columns I always get some kind of an error.
SELECT s.id, s.year, s.doy,
((s.year||'-01-01')::date + (s.doy||' days')::interval )::date AS date
FROM table_name AS s
the (s.year||'-01-01') or (s.doy||' days') concats the column value with a required string and the ::date or ::interval changes the resulting string type
You can use the make_date() function and add the number of days directly because date + integer is a valid operation:
select make_date(s.year, 1, 1) + s.doy as date
from ...

How to identify invalid dates in postgres table field?

I have a table in PostgreSQL that has two date fields ( start and end ). There are many invalid dates both date fields like 0988-08-11,4987-09-11 etc.. Is there a simple query to identify them? The data type of the field is DATE. Thanks in advance.
Values in a date column ARE valid per definition. The year 0988 = 988 is a valid historic date as well as the year 4987 which is far in the future.
To filter out dates which are too historic or too far in the future you simply make this query:
SELECT
date_col
FROM
table
WHERE
date_col < /* <MINIMUM DATE> */
OR date_col > /* <MAXIMUM DATE> */
For date ranges (your minimum and maximum date) you could use the daterange functionality:
https://www.postgresql.org/docs/current/static/rangetypes.html
https://www.postgresql.org/docs/current/static/functions-range.html
Example table:
start_date end_date
2015-01-01 2017-01-01 -- valid
200-01-01 900-01-01 -- completely too early
3000-01-01 4000-01-01 -- completely too late
0200-01-01 2000-01-01 -- begin too early
2000-01-01 4000-01-01 -- end too late
200-01-01 4000-01-01 -- begin too early, end too late
Query:
SELECT
start_date,
end_date
FROM
dates
WHERE
daterange('1900-01-01', '2100-01-01') #> daterange(start_date, end_date)
Result:
start_date end_date
2015-01-01 2017-01-01
demo:db<>fiddle
Those are valid dates, but if you have business rules that state they are not valid for your purpose, you can delete them based on those rules:
For example, if you don't want any dates prior to 1900 or after 2999, this statement would delete the records with those dates:
DELETE FROM mytable
WHERE
start_date < '1900-01-01'::DATE OR
start_date >= '2999-01-01'::DATE OR
end_date < '1900-01-01'::DATE OR
end_date >= '2999-01-01'::DATE;
If you want to replace the dates with the lowest/highest acceptable dates instead of deleting the entire record, you could do something like this:
UPDATE mytable
SET
start_date = least('2999-01-01'::DATE, greatest('1900-01-01'::DATE, start_date)),
end_date = least('2999-01-01'::DATE, greatest('1900-01-01'::DATE, end_date))
WHERE
start_date < '1900-01-01'::DATE OR
start_date >= '2999-01-01'::DATE OR
end_date < '1900-01-01'::DATE OR
end_date >= '2999-01-01'::DATE;

How to convert date format into milliseconds in postgresql?

I have date in postgresql in format "17/12/2011".
How can i convert it into milliseconds using select clause of postgreql ?
Currently i am just executing select clause as
select tableDate,tableSales
from table_name
I want to have something like when I select tableDate it should be converted into milliseconds using some postgresql functions.
tableDate DATE
tableSales Numeric
extract(epoch from ...) will return the number of seconds since 1970-01-01 00:00:00 so all you need to do is to multiply that by 1000:
select extract(epoch from tableDate) * 1000, tableSales
from table_name
More details in the manual:
http://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT

Postgresql: using 'with clause' to iterate over a range of dates

I have a database table that contains a start visdate and an end visdate. If a date is within this range the asset is marked available. Assets belong to a user. My query takes in a date range (start and end date). I need to return data so that for a date range it will query the database and return a count of assets for each day in the date range that assets are available.
I know there are a few examples, I was wondering if it's possible to just execute this as a query/common table expression rather than using a function or a temporary table. I'm also finding it quite complicated because the assets table does not contain one date which an asset is available on. I'm querying a range of dates against a visibility window. What is the best way to do this? Should I just do a separate query for each day in the date range I'm given?
Asset Table
StartvisDate Timestamp
EndvisDate Timestamp
ID int
User Table
ID
User & Asset Join table
UserID
AssetID
Date | Number of Assets Available | User
11/11/14 5 UK
12/11/14 6 Greece
13/11/14 4 America
14/11/14 0 Italy
You need to use a set returning function to generate the needed rows. See this related question:
SQL/Postgres datetime division / normalizing
Example query to get you started:
with data as (
select id, start_date, end_date
from (values
(1, '2014-12-02 14:12:00+00'::timestamptz, '2014-12-03 06:45:00+00'::timestamptz),
(2, '2014-12-05 15:25:00+00'::timestamptz, '2014-12-05 07:29:00+00'::timestamptz)
) as rows (id, start_date, end_date)
)
select data.id,
count(data.id)
from data
join generate_series(
date_trunc('day', data.start_date),
date_trunc('day', data.end_date),
'1 day'
) as days (d)
on days.d >= date_trunc('day', data.start_date)
and days.d <= date_trunc('day', data.end_date)
group by data.id
id | count
----+-------
1 | 2
2 | 1
(2 rows)
You'll want to convert it to using ranges instead, and adapt it to your own schema and data, but it's basically the same kind of query as the one you want.

How do I convert a date ( YYYY-MM-DD ) into a month number in postgresql?

I got a table:
CREATE TABLE TRANSACTION (
transaction_date date,
id_transaction int,
PRIMARY KEY (id_transaction)
);
and I want to compare the month of 'transaction_date' field with a number of month.
SELECT *
FROM TRANSACTION T
WHERE month = transaction_date;
but I don't know how to make this conversion.
You can use EXTRACT(MONTH FROM transaction_date)
SELECT *
FROM transaction
WHERE EXTRACT(MONTH FROM transaction_date) = 1;
sqlfiddle demo
As per the documentation:
EXTRACT (field FROM source)
The extract function retrieves subfields such as year or hour from
date/time values. source must be a value expression of type timestamp,
time, or interval.
SELECT *
FROM TRANSACTION T
WHERE EXTRACT(MONTH FROM TIMESTAMP transaction_date) = month;
month should be an integer between 1 (January) and 12 (December).