PostgreSQL: SELECT * from table WHERE timestamp IS WITHIN THIS MONTH - sql

For some reason I'm kind of lost on how to archive:
SELECT * FROM table WHERE timestamp IS WITHIN THIS MONTH;
I've looked at https://www.postgresql.org/docs/9.4/static/functions-datetime.html, but are only able to select X days backwards.
I'm running PostgreSQL 9.4

... WHERE date_trunc('month', timestamp)
= date_trunc('month', current_timestamp);
Alternatively:
... WHERE timestamp >= date_trunc('month', current_timestamp)
AND timestamp < date_trunc('month', current_timestamp) + INTERVAL '1 month';
The second version can use an index on timestamp, the first would need one on the expression date_trunc('month', timestamp).

Why don't you just filter the month with between ?
Pass the start of this month as variable1, and the end of this month as variable2...
SELECT * FROM table WHERE
timestamp >= __month_start AND timestamp < __next_month_start
e.g.
SELECT * FROM table
WHERE
(
timestamp >= '20170701'::timestamp
AND
timestamp < '20170801'::timestamp
)
Unlike using functions in the where-clause, this maintains sargability.

What Laurenz Albe suggested will work, however you're going to have a performance penalty because you'll lose cardinality on that field, you either have to index expression you're going to query (Apparently PostgreSQL allows to do that: https://www.postgresql.org/docs/current/static/indexes-expressional.html) or create a separate column to store yyyy-mm values and query it.

Related

Select entries created after a date, which have big integer timestamp

The table has a created_date column which has big integer as time stamp values. One of the time stamp looks like this 1596007131121. How can I query this?
select count(*) from user where created_date: date >='2020-08-30';
I need to query this.
You can convert that to a proper timestamp using the to_timestamp() function:
select *
from the_table
where to_timestamp(created_date/1000::bigint) >= date '2020-08-30';
But I would highly recommend to convert that column to a proper timestamp column.
I think you want:
select '1970-01-01'::timestamp + (created_date / 1000) * interval '1 second'
If you want this in a where clause, then use:
where created_date >= extract(epoch from '2020-08-30') * 1000
This has the nice feature that you can use an index.

Retrieve mean time between failure within given date range parameter

Below is what i have tried,
select machine_id, count(incident_id) "No_Incident",
(fail_date BETWEEN (24 * to_date('&From_date_', 'DDMMYYYY') AND to_date('&To_Date','DDMMYYYY') / count(incident_id))) "MTBF"
from mytable;
This will work for you:
SELECT machine_id, count(incident_id) "No_Incident",
MAX(ROUND((ABS((TO_DATE('01-02-2019','DD-MM-YYYY') -
TO_DATE('03-02-2019'||' 23:59:59','DD-MM-YYYY HH24:MI:SS'))*24))))
/count(incident_id) AS MTBF
FROM
mytable;
You may consider the following examples:
since machine_id is not being aggregated (eg. being counted), I have used the group by to provide the Mean Time Between failure (MTBF) for each machine. If you would like for all machines, simple remove machine_id from the SELECT clause and the GROUP BY machine_id
You had a syntax error with your query as you were querying the range of dates using the between in your select clause. NB. I have modified this and placed it in a where clause. Based on how you execute your query (eq sql clients), how you may handle parameters may differ.
Using Oracle
SELECT
machine_id,
count(incident_id) as "No_Incidents",
(
EXTRACT(
HOUR FROM
CAST(MAX(fail_date) AS TIMESTAMP) - CAST(MIN(fail_date) AS TIMESTAMP)
) +
EXTRACT(
DAY FROM
CAST(MAX(fail_date) AS TIMESTAMP) - CAST(MIN(fail_date) AS TIMESTAMP)
) * 24
)/count(incident_id) as "MTBF"
FROM
mytable
WHERE
fail_date BETWEEN to_date('&From_date_', 'DDMMYYYY') AND to_date('&To_Date','DDMMYYYY')
GROUP BY
machine_id
In the oracle example, I converted the dates using CAST to a TIMESTAMP before finding the difference (date_max - date_min gives a date interval ). Extracting (using EXTRACT) and summing the hours (hours and days*24) gives the total hours.
Using MySQL
SELECT
machine_id,
count(incident_id) as "No_Incidents",
(
TIMESTAMPDIFF(HOUR,min(fail_date),max(fail_date))
)/count(incident_id) as "MTBF"
FROM
mytable
WHERE
fail_date BETWEEN to_date('&From_date_', 'DDMMYYYY') AND to_date('&To_Date','DDMMYYYY')
GROUP BY
machine_id
I have also used the TIMESTAMPDIFF in MYSQL function to determine the difference between the dates in hours.

How can I extract just the hour of a timestamp using standardSQL

How can I extract just the hour of a timestamp using standardSQL.
I've tried everything and no function works. The problem is that I have to extract the time from a column and this column is in the following format:2018-07-09T02:40:23.652Z
If I just put the date, it works, but if I put the column it gives the error below:
Syntax error: Expected ")" but got identifier "searchIntention" at [4:32]
Follow the query below:
#standardSQL
select TOTAL, dia, hora FROM
(SELECT cast(replace(replace(searchIntention.createdDate,'T',' '),'Z','')as
DateTime) AS DIA,
FORMAT_DATETIME("%k", DATETIME searchIntention.createdDate) as HORA,
count(searchintention.id) as Total
from `searchs.searchs2016626`
GROUP BY DIA)
Please, help me. :(
How can I extract just the hour of a timestamp using standardSQL?
Below is for BigQuery Standard SQL
You can use EXTRACT(HOUR FROM yourTimeStampColumn)
for example:
SELECT EXTRACT(HOUR FROM CURRENT_TIMESTAMP())
or
SELECT EXTRACT(HOUR FROM TIMESTAMP '2018-07-09T02:40:23.652Z')
or
SELECT EXTRACT(HOUR FROM TIMESTAMP('2018-07-09T02:40:23.652Z'))
In BigQuery Standard SQL, you can use the EXTRACT timestamp function in order to return an INT64 value corresponding to the part of the timestamp that you want to retrieve, like.
The available parts includes a full list that you can check in the documentation page linked, but in your use case you can directly refer to the HOUR operator in order to retrieve the INT64 representation of the hour value in a field of TIMESTAMP type.
#standardSQL
# Create a table
WITH table AS (
SELECT TIMESTAMP("2018-07-09T02:40:23.652Z") time
)
# Extract values from a Timestamp expression
SELECT
EXTRACT(DAY FROM time) as day,
EXTRACT(MONTH FROM time) as month,
EXTRACT(YEAR FROM time) as year,
EXTRACT(HOUR FROM time) AS hour,
EXTRACT(MINUTE FROM time) as minute,
EXTRACT(SECOND from time) as second
FROM
table

How to run PostgreSQL Query every day with updated values?

New to SQL, but trying to learn/do a job for a friend. I have a query set up that returns the number of bookings for the day. Example snippet:
...
WHERE be.event IN ('instant_approve', 'approve') AND TO_CHAR(be.created_at, 'yyyy-mm-dd') BETWEEN '2017-06-26' AND '2017-06-26';
Now, this query is set up for just today. How can I set this up so that tomorrow the query is executed for '2017-06-27' and so on? Is this possible?
Built-in function now() gives you a timestamp of the beginning of your transaction (CURRENT_TIMESTAMP pseudo-constant is its "alias", a part of SQL standard, but I prefer using the function).
Another function, date_trunc() gives you a "truncated" timestamp and you can choose, how to truncate it. E.g., date_trunc('day', now()) will give you the date/time of beginning of the current day.
Also, you can add or subtract intervals easily, so here is an example that gives you the beginning of the current and the next days:
select
date_trunc('day', now()) cur_day_start,
date_trunc('day', now() + interval '1 day') as next_day_start
;
Also, I would not use to_char() or anything else on top of created_at column -- this will not allow Postgres planner use index on top of this field. If you do want to use to_char(), then consider adding a functional index over to_char(created_at, 'yyyy-mm-dd').
Here is how I would retrieve records generated at July 26, 2017:
where
created_at between '2017-06-26' and '2017-06-27'
(implicit type casting from text to timestamps here)
This is equivalent to
where
created_at >= '2017-06-26'
and created_at <= '2017-06-27'
-- so all timestamps generated for July 26, 2017 will match. And for such query Postgres will use a regular index created for created_at column (if any).
"Dynamic" version:
where
created_at between
date_trunc('day', now())
and date_trunc('day', now()) + interval '1 day'
Use current_date built-in function in the between condition and it will work only for today's bookings.
.........
WHERE be.event IN ('instant_approve', 'approve') AND TO_CHAR(be.created_at, 'yyyy-mm-dd') =current_date;

Filter Data for 30 months using subquery with INTERVAL function in Teradata

I would like to filter out the data using a sub query in the interval function
Following is the query i use
SEL * FROM my_table WHERE MY_DATE < CURRENT_DATE- INTERVAL '30' MONTH;
The above query works, However i want to parameterize the period '30' using a sub query. Please suggest how to achieve this.
Thanks in Advance
Don't use interval calculations with year/month as it will fail, e.g. DATE '2016-12-31' + INTERVAL '30' MONTH results in 2019-06-31 (according to Standard SQL) which obviously doesn't exist.
SELECT *
FROM my_table
WHERE MY_DATE < ADD_MONTHS(CURRENT_DATE, (SELECT -col FROM tab));
If col is actually an INTERVAL you need to cast it to an INT.