Postgresql - query problem - sql

I have a variable which is in this format 2011-05-13.
I want to make a query that adds one day to this variable and searches for days like this in the database.
I made this query but it doesnt work.
select phone from employee where date like (select date '2011-05-13' + 1) %
Can anyone help?

You need an INTERVAL:
SELECT phone FROM employee WHERE datefield = (date '2011-05-13' + INTERVAL '1 DAY') ;
Edit: Don't use LIKE when you're working with dates, there is no LIKE for a date.

Try the following:
SELECT phone FROM employee WHERE to_char(date, 'yyyy-mm-dd')::timestamp = ('2011-05-13'::timestamp + '1 day'::interval)

Related

H2 Get Date 1 day old from current time

I'm currently working on a really fun problem. I want to get a date that is one day old (from current date) and then compare it to now.
The exact way to do this in PostreSQL is this:
select * from table WHERE date < now() - '1 day'::interval;
How do I do this in H2 JDBC? Does anybody know?
Grateful for any assistance!
Simply subtract the number of days from current_date
select *
from the_table
where the_date_column < current_date - 1;
The above would work in Postgres just as well.
You can try the DATEADD function. It works for addition and subtraction:
select * from table WHERE date < DATEADD('DAY', -1, CURRENT_DATE);

Add number of days in given date

In PostgreSQL:
Let say:
SELECT DATE(NOW())+interval '1 day';
It will show date tomorrow.
Problem:
While I having a column duration in table tbl, following SQL does not work :
SELECT DATE(NOW())+interval duration || ' day' from tbl;
I just wondering how to make the '1 day' become a variable instead of a constant.
Do not try to make '1day' a variable, just multiply it by duration variable:
SELECT DATE(NOW()+duration * INTERVAL '1day') FROM tbl;

PostgreSQL: SELECT integers as DATE or TIMESTAMP

I have a table where I have multiple integer columns: year, month and day. Unfortunately, while the three should have been grouped into one DATE column from the beginning, I am now stuck and now need to view it as such. Is there a function that can do something along the lines of:
SELECT makedate(year, month, day), othercolumn FROM tablename;
or
SELECT maketimestamp(year, month, day, 0, 0), othercolumn FROM tablename;
You can
SELECT format('%s-%s-%s', "year", "month", "day")::date
FROM ...
or use date maths:
SELECT DATE '0001-01-01'
+ ("year"-1) * INTERVAL '1' YEAR
+ ("month"-1) * INTERVAL '1' MONTH
+ ("day"-1) * INTERVAL '1' DAY
FROM ...
Frankly, it's surprising that PostgreSQL doesn't offer a date-constructor like you describe. It's something I should think about writing a patch for.
In fact, a quick look at the sources shows that there's an int date2j(int y, int m, int d) function at the C level already, in src/backend/utils/adt/datetime.c. It just needs to be exposed at the SQL level with a wrapper to convert to a Datum.
OK, now here's a simple makedate extension that adds a single function implemented in C, named makedate. A pure-SQL version is also provided if you don't want to compile and install an extension. I'll submit the C function for the 9.4 commitfest; meanwhile that extension can be installed to provide a fast and simple date constructor:
regress=# SELECT makedate(2012,01,01);
makedate
------------
2012-01-01
(1 row)
PostgreSQL 9.4+
In PostgreSQL 9.4, a function was added to do just this
make_date(year int, month int, day int)
There may be a more elegant method, but this will give you a date.
select to_date(to_char(year * 10000 + month * 100 + day,'00000000'), 'yyyymmdd')
from tablename;
Try something like:
SELECT year * interval '1 year' +
month * interval '1 month' +
day * interval '1 day'
FROM tablename;

How to retrieve the records based on a date from oracle database

I have a table with date column in it. I need to fetch the records from it based on
the given date.
Currently when i used the query:
select * from workingemployee_data where created_date like '20-Jan-2012'
I am getting those records which have created_date on 20-Jan-2012
But i want to get the records those were created 10 days earlier to a given
date (i.e) 20-Jan-2012.
Please suggest me on this.
This gives all records between today and 10 days ago:
SELECT *
FROM workingemployee
WHERE created_date BETWEEN sysdate - INTERVAL '10' DAY
AND sysdate
This gives all records entered exactly 10 days ago:
SELECT *
FROM workingemployee
WHERE created_date = sysdate - INTERVAL '10' DAY
Replace sysdate with exact date if you want.
Why do you use like and not = ?
Assuming that created_date is of type DATE, it's bad practice to rely on implicit conversion according to NLS_DATE_FORMAT (this is what happens when you compare a date and a string)
dd-mon-yyyy isn't a good format for querying since it deffers according to NLS_LANGUAGE better use mm for months numbers
So, either use #mvp's answer or do something like this:
SELECT *
FROM workingemployee
WHERE trunc(created_date) = to_date('20-01-2013', 'dd-mm-yyyy') - 10
SELECT *
FROM workingemployee
WHERE created_date > sysdate - INTERVAL '10' DAY;

Optimizing SQL Query and Dynamically using current date

I am trying to optimize a simple SQL query and was wondering if anyone has any suggestions. I am developing using Oracle SQL Developer (which I don't like) on an Oracle 11g database. The query I am using is:
SELECT count(*)
FROM my_table
WHERE my_date
BETWEEN TO_DATE('2012-5-09T05.00.00','YYYY-MM-DD"T"HH24:MI:SS')
AND TO_DATE('2012-5-10T04.59.59','YYYY-MM-DD"T"HH24:MI:SS')
AND my_code='33'
GROUP BY my_code;
Also, I want to be able to use this query dynamically by changing the part of the date to be whatever the current date is, but I want to be able to specify the hour. So I want to be comparing something like:
getdate() + 'T05.00.00'
I have no idea how to do this and the getdate() function doesn't seem to work in SQL Developer/I don't know how to use it correctly.
So what I'm looking for is optimization suggestions and pointers on how to just dynamically change the day-month-year part of the date I want to constrain my results to. Thanks!
To get current date, you can use SYSDATE. To add x number of hours to it, you can add x/24. So something like this:
Example: Get current date + 5 hours
SELECT SYSDATE + 5/24 FROM dual
So in your example:
SELECT count(*)
FROM my_table
WHERE my_date
BETWEEN sysdate
AND sysdate + 5/24 -- if you want 5 hours ahead, for example
AND my_code='33'
GROUP BY my_code;
If you want to be able to change the number of hours, you could make this code into a function, and pass in the hours and code as variables.
Something like this:
CREATE FUNCTION myfunc
(
p_num_hours INT
, p_my_code VARCHAR
) RETURN INT
AS
l_ret INT;
BEGIN
SELECT count(*)
INTO l_ret
FROM my_table
WHERE my_date
BETWEEN sysdate
AND sysdate + p_num_hours/24
AND my_code=p_my_code
RETURN l_ret;
END;
As an alternative to adding fractional days via expressions such as "5 / 24" you might want to use an INTERVAL constant. For example:
SELECT count(*)
FROM my_table
WHERE my_date BETWEEN (TRUNC(SYSDATE) + INTERVAL '5' HOUR)
AND (TRUNC(SYSDATE) + INTERVAL '1' DAY +
INTERVAL '5' HOUR - INTERVAL '1' SECOND) AND
my_code='33'
GROUP BY my_code
I like to use INTERVAL constants because it's quite clear what these constants represent. With the fractional-day constants I sometimes get confused ('course, I sometimes get confused, regardless... :-)
Share and enjoy.
If I understand correctly, something like
select count(*)
from my_table
where trunc(my_date) = trunc(sysdate)
and my_code = '33'
group by my_code;
or
select count(*)
from my_table
where my_date
between sysdate and sysdate + 5/24
and my_code = '33'
group by my_code;
HTH.
Alessandro