Is that possible? Can one
SELECT * FROM DATES_TBL WHERE DATES_TBL.DATES IN(NULL, >=SYSDATE)
? Maybe I am formatting it incorrectly, or missing a tick?
What I would like to select are values from the date field that are NULL or greater than today's date (>=SYSDATE). Any help would be appreciated.
SQL 10g
SELECT *
FROM DATES_TBL
WHERE DATES IS NULL OR DATES >= SYSDATE
The NULL value is a special value so you must write your statement like that:
SELECT *
FROM DATES_TBL
WHERE DATES IS NULL
OR DATES >= SYSDATE
This is definitely not a valid syntax: IN queries require specific items; also, because in SQL null never equals anything, including other nulls, it does not make sense to put nulls into an IN list.
What you need instead is an OR:
SELECT * WHERE (DATES_TBL.DATES IS NULL) OR (DATES_TBL.DATES>=SYSDATE)
-- ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
-- | |
-- | +- This is how you compare for >=
-- +------------- This is how you check for NULL
Every time I try to use an OR clause it causes a lot of run time
In cases when OR is introduced to combine non-overlapping results (which is true in this case, because a column is either null or is greater than SYSDATE, but not both) you can use UNION ALL to potentially speed up the search:
SELECT * WHERE DATES_TBL.DATES IS NULL
UNION ALL
SELECT * WHERE DATES_TBL.DATES >= SYSDATE
You need to make sure that DATES_TBL.DATES column is indexed.
Assuming this is for Oracle, try this:
SELECT * FROM DATES_TBL WHERE (DATES_TBL.DATES is null or DATES_TBL.DATES >= sysdate)
The parenthesis make it work.
Related
I have a question regarding Oracle SQL case statement.
in the where condition I would like to apply the following condition.
if salary_date is null then effective_date should be greater than 01-Jan-2016
I have the tried as
case when salary_date is null then
trunc(effective_date) >= '01-JAN-2016' else
null end
However the above resulted in
ORA-00933: SQL command not properly ended
How can I resolve this?
The problem with your code is that SQL interpreter expects to see the value after 'then' keyword, whereas you have a condition clause.
Try something like this maybe:
case when salary_date is null and trunc(effective_date) >= '01-JAN-2016'
then <value you need>
else null
You can try this without CASE statement
SELECT
..
..
WHERE ( trunc(effective_date) >= '01-JAN-2016' AND salary_date is null )
OR ( <some other condition> )
...where salary_date is not null or effective_date >= date '2016-01-01'
Since Oracle SQL does not have "IF... THEN", use basic logic to transform your boolean expression. IF a THEN b is the same thing as (NON a) OR b. This is what I did above.
DO...NOT... compare dates to strings. '01-JAN-2016' is a string, not a date. You MUST convert it to a date, for example with to_date('01-JAN-2016', 'dd-MON-yyyy').
Or, as an alternative, note how I input a "date literal" (a fixed date). If I don't need to input a time of day, I can use the expression date '2016-01-01', which is a SQL Standard (ANSI) "date literal". Then you don't need to give a date format model; it MUST ALWAYS be in the exact format yyyy-mm-dd.
So, i´m trying to select rows between two dates.
In db, the dates also have time.
Therefor i need to use LIKE.
SQL
$query = "SELECT * FROM table WHERE date >= LIKE :selectedDateFrom AND <= LIKE :selectedDateTo";
$query_params = array(':selectedDateFrom' => $selectedDateFrom.="%", ':selectedDateTo' => $selectedDateTo.="%");
This one returns error!
How should it look like?
In db, the dates also have time.
Therefor i need to use LIKE.
No, you don't.
To select all date/times where the date component is between (from) and (to), inclusive, you can write it as
SELECT *
FROM table
WHERE date >= :selectedDateFrom
AND date < :selectedDateToPlusOne
(Note the < instead of <=, and set the second parameter to one day after the last day you want to include in your results.) This works even when the column includes times.
you can't use like with dates in SQL
SO use this:
$query = "SELECT * FROM table WHERE date >= :selectedDateFrom AND date <= :selectedDateTo";
You'd strip the time part from a datetime with DATE().
SELECT *
FROM mytable
WHERE date(mydate) >= :selectedDateFrom
AND date(mydate) <= :selectedDateTo;
Or with BETWEEN for better readability:
SELECT *
FROM mytable
WHERE date(mydate) BETWEEN :selectedDateFrom AND :selectedDateTo;
I have a table for matches. The table has a column named matchdate, which is a datetime field.
If I have 3 matches on 2011-12-01:
2011-12-01 12:00:00
2011-12-01 13:25:00
2011-12-01 16:00:00
How do I query that? How do I query all matches on 1 single date?
I have looked at date_trunc(), to_char(), etc.
Isn't there some "select * where datetime in date" function?
Cast your timestamp value to date if you want simple syntax. Like this:
SELECT *
FROM tbl
WHERE timestamp_col::date = '2011-12-01'; -- date literal
However, with big tables this will be faster:
SELECT *
FROM tbl
WHERE timestamp_col >= '2011-12-01 0:0' -- timestamp literal
AND timestamp_col < '2011-12-02 0:0';
Reason: the second query does not have to transform every single value in the table and can utilize a simple index on the timestamp column. The expression is sargable.
Note excluded the upper bound (< instead of <=) for a correct selection.
You can make up for that by creating an index on an expression like this:
CREATE INDEX tbl_ts_date_idx ON tbl (cast(timestamp_col AS date));
Then the first version of the query will be as fast as it gets.
not sure if i am missing something obvious here, but i think you can just
select * from table where date_trunc('day', ts) = '2011-12-01';
Just use the SQL BETWEEN function like so:
SELECT * FROM table WHERE date BETWEEN '2011-12-01' AND '2011-12-02'
You may need to include times in the date literals, but this should include the lover limit and exclude the upper.
From rails I believe you can do:
.where(:between => '2011-12-01'..'2011-12-02')
My table has records like these
23-MAY-11 11.40.39.000000 AM
The following query brings nothing
SELECT *
FROM my_table
WHERE tenant_pha = 'test'
AND create_date >= TO_DATE('05/10/2011','mm/dd/yyyy')
AND create_date <= TO_DATE('05/23/2011','mm/dd/yyyy')
However, the below query will bring data
SELECT *
FROM my_table
WHERE tenant_pha = 'test'
AND create_date >= TO_DATE('05/10/2011','mm/dd/yyyy')
AND create_date <= TO_DATE('05/24/2011','mm/dd/yyyy')
I think this is because create_date column is time stamp.
How can I change my query to bring the desired result ( I want to avoid doing functions on the left side columns because they will make the query long).
You are right about the timestamp. '05/23/2011' is the same as '05/23/2011 12:00 AM'.
To include the whole day I usually move my date up by a day. < '05/24/2011' will include all of 5/23.
or change to '05/23/2011 23:59:59'
You can use trunc() without problems, you only need to create a function based index.
If you create this index:
CREATE INDEX idx_trunc_date ON my_table (trunc(create_date));
then the following condition will make use of that index:
AND trunc(create_date) >= TO_DATE('05/10/2011','mm/dd/yyyy')
Suppose I have a date 2010-07-29. Now I would like to check the result of one day ahead. how to do that
For example,
SELECT *
from table
where date = date("2010-07-29")
How to do one day before without changing the string "2010-07-29"?
I searched and get some suggestion from web and I tried
SELECT *
from table
where date = (date("2010-07-29") - 1 Day)
but failed.
MySQL
SELECT *
FROM TABLE t
WHERE t.date BETWEEN DATE_SUB('2010-07-29', INTERVAL 1 DAY)
AND '2010-07-29'
Change DATE_SUB to DATE_ADD if you want to add a day (and reverse the BETWEEN parameters).
SQL Server
SELECT *
FROM TABLE t
WHERE t.date BETWEEN DATEADD(dd, -1, '2010-07-29')
AND '2010-07-29'
Oracle
SELECT *
FROM TABLE t
WHERE t.date BETWEEN TO_DATE('2010-07-29', 'YYYY-MM-DD') - 1
AND TO_DATE('2010-07-29', 'YYYY-MM-DD')
I used BETWEEN because the date column is likely DATETIME (on MySQL & SQL Server, vs DATE on Oracle), which includes the time portion so equals means the value has to equal exactly. These queries give you the span of a day.
If you're using Oracle, you can use the + and - operators to add a number of days to a date.
http://psoug.org/reference/date_func.html
Example:
SELECT SYSDATE + 1 FROM dual;
Will yield tomorrow's date.
If you're not using Oracle, please tell use what you ARE using so we can give better answers. This sort of thing depends on the database you are using. It will NOT be the same across different databases.
Depends of the DateTime Functions available on the RDBMS
For Mysql you can try:
mysql> SELECT DATE_ADD('1997-12-31',
-> INTERVAL 1 DAY);
mysql> SELECT DATE_SUB('1998-01-02', INTERVAL 31 DAY);
-> '1997-12-02'
If youre using MSSQL, you're looking for DateAdd() I'm a little fuzzy on the syntax, but its something like:
Select * //not really, call out your columns
From [table]
Where date = DateAdd(dd, -1, "2010-07-29",)
Edit: This syntax should be correct: it has been updated in response to a comment.
I may have the specific parameters in the wrong order, but that should get you there.
In PL SQL : select sysdate+1 from dual;