operator does not exist: integer + interval - sql

I have next part of query:
AND date_part('day', some_date::date - first_day::date + interval '1 day') = some_daye
and I am getting next error:
ERROR: operator does not exist: integer + interval
How I can cast 'some_date - first_day' to interval?

Subtracting a date from a date yields an integer.
An integer cannot be cast to an interval.
Cast either of your date values to timestamp to get an interval.
e.g. AND date_part('day', some_date::timestamp - first_day + interval '1 day') = some_daye
Or you could simplify the entire expression as AND some_date - first_day + 1 = some_daye

Related

How to select all rows created in the last hour?

My query is
SELECT * FROM email_operation WHERE cdate = CURRENT_DATE and ctime >= (NOW() - INTERVAL '1 hour' )
to select all rows created at the last hour but it doesn't work. It throws an error at >=
SELECT * FROM email_operation WHERE cdate = CURRENT_DATE and ctime >= (NOW() - INTERVAL '12 hour' )
> ERROR: operator does not exist: time without time zone >= timestamp with time zone
LINE 1: ..._operation WHERE cdate = CURRENT_DATE and ctime >= (NOW() ...
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
> Time: 0.001s
Apparently ctime is a time column, so you can't compare it with a timestamp (which is what the error message tells you). You need to use current_time instead:
and ctime >= current_time - interval '1 hour'
Note that this won't work properly around midnight.
It seems you have split up date and time into two columns (which is a bad idea), but you can combine them to compare a timestamp:
and cdate + ctime >= current_timestamp - interval '1 hour'
If you want results in the past hour and you have separated the date and time components, then one method is:
WHERE (cdate + ctime) >= NOW() - INTERVAL '1 hour'
Note that this will even work between midnight and 1:00 a.m. Sadly, it probably won't use indexes. That might be an issue if you have lots of data. Here is one method that will at least use an index on cdate:
WHERE cdate IN (CURRENT_DATE, CURRENT_DATE - INTERVAL '1 day') AND
( (cdate + ctime) >= NOW() - INTERVAL '1 hour' )
where (cdate + ctime)::timestamp(0) >= (now() - interval '1 hour')

How many days does SQL define a year interval?

Query:
SELECT
CAST ('2010-12-13' AS TIMESTAMP) - CAST ('2007-01-01' AS TIMESTAMP) <= INTERVAL '4 years',
CAST ('2010-12-13' AS TIMESTAMP) <= CAST ('2007-01-01' AS TIMESTAMP) + INTERVAL '4 years',
CAST ('2010-12-13' AS TIMESTAMP) - CAST ('2008-01-01' AS TIMESTAMP) <= INTERVAL '3 years',
CAST ('2010-12-13' AS TIMESTAMP) <= CAST ('2008-01-01' AS TIMESTAMP) + INTERVAL '3 years'
Result: false true true true
Why the 1st column CAST ('2010-12-13' AS TIMESTAMP) - CAST ('2007-01-01' AS TIMESTAMP) <= INTERVAL '4 years' returns FALSE??
I think I figure it out. Interval ‘1 year’ includes only 360 days.
Column 1: left = 1442 days, right = 360 * 4 = 1440 days —> return false
Column 2: in the right expression, 2007 (year part of 2007-01-01) + 4 (the 4 year interval) = 2011 —> right = ‘2011-01-01’
Column 3: left = 1077 days, right = 360 * 3 = 1080 days —> return true

Having trouble with SQL Interval

I need to get the sum of data from a particular date going back one year. But I am having difficult with the Interval
Select 0 - sum(l.icdetailquantity )
from inventoryline l
where l.icmasterid = 'WAD185967E' and l.icdetailtranstype = 5
and l.icdetaildate <= '01-Jan-2019' and l.icdetaildate > Now() - interval '1 year'
This works as expected but I need to passs a date not use Now()
Select 0 - sum(l.icdetailquantity )
from inventoryline l
where l.icmasterid = 'WAD185967E' and l.icdetailtranstype = 5
and l.icdetaildate <= '01-Jan-2019' and l.icdetaildate > '01-Jan-2019' - interval '1 year'
the second SQl give an error
ERROR: invalid input syntax for type interval: "01-Jan-2019"
LINE 4: ...detaildate <= '01-Jan-2019' and l.icdetaildate > '01-Jan-20...
You're trying to subtract a year from a string. This does not work, you have to first cast youru string to a date object using:
to_date(date_string,format)
Example that will work for you:
to_date('01-Jan-2019', 'DD-Mon-YYYY') - interval '1 year'
http://www.postgresqltutorial.com/postgresql-to_date/
Have you tried with
Select 0 - sum(l.icdetailquantity )
from inventoryline l
where l.icmasterid = 'WAD185967E'
and l.icdetailtranstype = 5
and l.icdetaildate <= date '2019-01-01'
and l.icdetaildate > date '2019-01-01' - interval '1 year'
From the documentation I'm looking at (https://www.postgresql.org/docs/current/functions-datetime.html) the "date" keyword seems to be necessary.

Add additional column in a SELECT statement based on values of other columns PSQL

I have a table of driver licenses per person and know when a person acquired the drivers license. The validity of the drivers license can either be X days from the day you acquired it or a specific date.
acquired relative specific_date valid_type expiration_date
----------------------------------------------------------------------------------
2015-02-05 500 null days
2015-02-05 null 2016-03-05 date
2015-02-05 200 null days
2015-02-05 null 2016-02-22 date
My query right now would be:
SELECT acquired,
relative_date,
specific_date,
valid_type
FROM person_drivers_license
WHERE (valid_type = 'days'
AND (EXTRACT(epoch
FROM acquired) - EXTRACT(epoch
FROM now()))/86400 + relative_date > 0)
OR (valid_type = 'DATE'
AND specific_date >= now()));
I am trying to add an expiration_date column with the select statement above. If it is a specific date, just take the date and put it in expiration_date and if it is a relative date, calculate the expiration date with the help of the acquired date. Is this possible in PSQL?
First - there is a simpler way to do date math in postgres. You can use something like:
acquired + relative_date * interval '1 day' >= current_date
or
acquired + relative_date >= current_date
-- any integer can be treated as interval in days for date mathematics is SQL
For the question - try one of this:
CASE WHEN valid_type = 'days'
THEN acquired + relative_date * interval '1 day'
WHEN valid_type = 'date'
THEN specific_date
--ELSE ??? you may specify something here
END
or
COALESCE(specific_date, acquired + relative_date * interval '1 day')
The query may look like:
SELECT acquired,
relative_date,
specific_date,
valid_type,
COALESCE(specific_date, acquired + relative_date * interval '1 day') as valid_date
FROM person_drivers_license
WHERE COALESCE(specific_date, acquired + relative_date * interval '1 day') >= current_date
Try this:
SELECT acquired,
relative_date,
specific_date,
valid_type
CASE valid_type
WHEN 'days' THEN acquired + relative_date
WHEN 'date' THEN specific_date
ELSE NULL
END AS expiration_date
FROM person_drivers_license;
You don't need pl/sql
SELECT acquired,
relative_date,
specific_date,
valid_type,
CASE WHEN specific date = "date" -- starts here
THEN specific date
ELSE acquired + cast('1 months' as interval)END
AS expiration_date -- end here
FROM person_drivers_license
WHERE (valid_type = 'days'
AND (EXTRACT(epoch
FROM acquired) - EXTRACT(epoch
FROM now()))/86400 + relative_date > 0)
OR (valid_type = 'DATE'
AND specific_date >= now()));

Adding a year in PostgreSQL

select current_date
Will return
Date
----
2014-10-16
so is there any function or way to get the same day and month with next year, I.e
next_year_date
----
2015-10-16
select
(current_date + interval '1 year')::date next_year_date
Or
select
date (now()::date + interval '1 year') next_year_date
Date/Time Functions and Operators