Why "=" Operator not giving the expected result in SQL Query? - sql

I am trying to get the row from the Database which saves the date in the following format 2018-07-09 13:22:40
When I write the following query like this:-
SELECT *
FROM table_name
WHERE time_col = '2018-07-09 13:22:40';
it returns a single row
But When I write a query like this (no result):
SELECT *
FROM table_name
WHERE time_col = '2018-07-09';
it returns me nothing.
For the other operators, it works for <, >, <=, >= with the following query but why not with "=" Operator
SELECT *
FROM table_name
WHERE time_col < '2018-07-09';

Assuming your column is of type timestamp, then the string constant '2018-07-09' will be converted to a timestamp by Postgres - but with the time as 00:00:00.
So the following query:
SELECT *
FROM table_name
WHERE time_col = '2018-07-09';
is actually run as:
SELECT *
FROM table_name
WHERE time_col = timestamp '2018-07-09 00:00:00';
Which of course does not match the value 2018-07-09 13:22:40.
To get the rows on a specific day, you can cast the timestamp column to a date:
SELECT *
FROM table_name
WHERE time_col::date = date '2018-07-09'
This will however prevent the usage on the time_col column. So if that version of the query is slow, you have to revert to a range query:
SELECT *
FROM table_name
WHERE time_col >= timestamp '2018-07-09 00:00:00'
and time_col < timestamp '2018-07-10 00:00:00'

It does not work cause column is timestamp (date with time). But you trying compare that with date(no date), that is why they are not equal.
Use trunc function in oracle. trunc function cuts time from date and leaves only date:
SELECT * FROM table_name WHERE trunc(time_col) = '2018-07-09';
And for postgres use explicit cast:
SELECT * FROM table_name WHERE time_col::date = '2018-07-09';

SELECT *FROM table
WHERE update_date >= '2013-05-03'::date
AND update_date < ('2013-05-03'::date + '1 day'::interval);

Related

SQL BETWEEN Statement is returning only match results

I am using SQL Oracle DB, I am facing issue when using SQL Between Statement.
I have a requirement to search the values in between the date time range.
When I am using the below SQL statement, I am only receiving matching results or empty set but I need the results which are between the values inclusive the passing values if present.
select id,date
from Table_name
where date between '2020-10-21 10:00:17' AND '2017-10-21 22:00:17'
and id = '123';
I am receiving as Empty set
Example of output should be
ID DATE
123 2020-10-21 10:00:17
123 2020-09-07 09:87:22
123 2018-06-09 07:58:01
123 2017-08-12 08:00:10
Could anyone suggest what should be modified in the sql statement
Try to swap the two date values after between in your SQL statement.
Explanation: between in this statement means:
date >= '2020-10-21 10:00:17' and date <= '2017-10-21 22:00:17'
The correct statement is:
select id, date
from Table_name
where date between '2017-10-21 22:00:17' and '2020-10-21 10:00:17'
and id = '123';
You have two problems:
You want the lower bound of the range before the upper bound in the BETWEEN clause; and
You are not comparing on a date-time range, you are comparing on an alpha-numeric string comparison. This is because the values in the BETWEEN clause are string literals and not DATE values.
You want to use DATE values in the BETWEEN clause:
select id,
date_column
from Table_name
where date_column BETWEEN DATE '2017-10-21' + INTERVAL '22:00:17' HOUR TO SECOND
AND DATE '2020-10-21' + INTERVAL '10:00:17' HOUR TO SECOND
and id = '123';
or
select id,
date_column
from Table_name
where date_column BETWEEN TIMESTAMP '2017-10-21 22:00:17'
AND TIMESTAMP '2020-10-21 10:00:17'
and id = '123';
or
select id,
date_column
from Table_name
where date_column BETWEEN TO_DATE('2017-10-21 22:00:17', 'YYYY-MM-DD HH24:MI:SS')
AND TO_DATE('2020-10-21 10:00:17', 'YYYY-MM-DD HH24:MI:SS')
and id = '123';
If you use string literals and the NLS_DATE_FORMAT session parameter does not match then you will get an error:
select id,
date_column
from Table_name
where date_column between '2017-10-21 22:00:17' and '2020-10-21 10:00:17'
and id = '123';
Outputs:
ORA-01861: literal does not match format string
db<>fiddle here

How to select date from timestamp column in Oracle SQL Developer?

I have table in Oracle SQL Developer like below:
col1
--------
2019-11-29 11:14:00.821822
2020-02-11 09:14:00.821847
And I would like to select only rows where date is '2019-11-29' how can I do that?
You can use:
where trunc(col1) = date '2019-11-29'
However, that cannot use an index on col1. So, it is often better to use:
where col1 >= date '2019-11-29' and
col1 < date '2019-11-30'
You can to_date() or to_char() functions. The Oracle/PLSQL TO_DATE function converts a string to a date and TO_CHAR function converts a date to a String. The TRUNC(date) function returns date without the time portion.
select *
from myTable
where trunc(col1) = to_date('2019-11-29', 'yyyy-mm-dd');
or:
select *
from myTable
where to_char(col1, 'yyyy-mm-dd') = '2019-11-29'

How to search by to_date function?

I have table as below:
Table Temp:
ID MAX MIN DATE_C
1 34 24 21-APR-17 02.41.38.520000 PM
2 32 26 20-APR-17 02.42.44.569000 PM
I execute the below SQL query to get temperature details on respective date:
SELECT *
FROM Temp t
WHERE t.date_c = TO_DATE( '2017-04-21', 'YYYY-MM-DD')
order by t.id
But it's returning empty records. Whats wrong with my query?
You need to remove the time component on the column. Here is one way:
SELECT *
FROM Temp t
WHERE TRUNC(t.date_c) = DATE '2017-04-21'
ORDER BY t.id;
However, I usually recommend using inequalities, rather than a function on the column:
SELECT *
FROM Temp t
WHERE t.date_c >= DATE '2017-04-21' AND
t.date_c < DATE '2017-04-22'
ORDER BY t.id;
This allows the query to use an index on date_c. I should add that the original version can use an index on (trunc(date_c, id).
21-APR-17 02.41.38.520000 PM is not a DATE; it has a fractional seconds component so it is a TIMESTAMP.
So, if you want to find items that are on a particular day (inputting the TIMESTAMP using an ISO/ANSI timestamp literal):
SELECT *
FROM Temp
WHERE date_c >= TIMESTAMP '2017-04-21 00:00:00' AND
date_c < TIMESTAMP '2017-04-21 00:00:00' + INTERVAL '1' DAY;
or
SELECT *
FROM Temp
WHERE date_c >= TO_TIMESTAMP( :your_date_string, 'YYYY-MM-DD' ) AND
date_c < TO_TIMESTAMP( :your_date_string, 'YYYY-MM-DD' ) + INTERVAL '1' DAY;
it's returning empty records. Whats wrong with my query?
date_c = TO_DATE( '2017-04-21', 'YYYY-MM-DD') matches all rows where the date_c value is exactly 2017-04-21 00:00:00.000000 (including the time component); if you do not have any rows with exactly that date and time then, as you noticed, it will return nothing. If you want to get records matching that day then you need to get values within a range of times between the start and end of the day.
You need to pass date on the column. Here is a way...
SELECT *
FROM Temp t
WHERE CAST(t.CREATED_ON as date)= N'2017-04-22'
ORDER BY t.id

SQL: Convert date to timestamp

How can I convert a date to a timestamp?
My query:
SELECT * FROM CTP0421
WHERE timestamp <= '2016-04-04'
This doesn't work for me.
SELECT * FROM CTP0421
WHERE trunc(timestamp) <= to_date('2016-04-04','yyyy-mm-dd');

Postgresql - select something where date = "01/01/11"

I have a datetime field in my Postgresql, named "dt".
I'd like to do something like
SELECT * FROM myTable WHERE extract (date from dt) = '01/01/11'
What is the right syntax to do that?
Thanks!
I think you want to cast your dt to a date and fix the format of your date literal:
SELECT *
FROM table
WHERE dt::date = '2011-01-01' -- This should be ISO-8601 format, YYYY-MM-DD
Or the standard version:
SELECT *
FROM table
WHERE CAST(dt AS DATE) = '2011-01-01' -- This should be ISO-8601 format, YYYY-MM-DD
The extract function doesn't understand "date" and it returns a number.
With PostgreSQL there are a number of date/time functions available, see here.
In your example, you could use:
SELECT * FROM myTable WHERE date_trunc('day', dt) = 'YYYY-MM-DD';
If you are running this query regularly, it is possible to create an index using the date_trunc function as well:
CREATE INDEX date_trunc_dt_idx ON myTable ( date_trunc('day', dt) );
One advantage of this is there is some more flexibility with timezones if required, for example:
CREATE INDEX date_trunc_dt_idx ON myTable ( date_trunc('day', dt at time zone 'Australia/Sydney') );
SELECT * FROM myTable WHERE date_trunc('day', dt at time zone 'Australia/Sydney') = 'YYYY-MM-DD';