Mysql Select with Dates and maybe Case when - mysql

im having a problem where i cant think of a solution, maybe im having a bad table-structure or i just dont know enough about mysql select commands to think of a good solution. Maybe you can help me out:
So i got a table that has a Column with the Date-format (yyyy-mm-dd) i wanted to select all upcoming dates so i did:
SELECT * WHERE date >= now.
This worked kinda well but i also got "dates" where only the year is entered (2014-00-00) i also wanted to select these but "now" is already bigger so i made another column with the year only and if the month, date or both arent known i will use 0000-00-00 and the Column "year" now i could select like this:
SELECT * WHERE date >= now AND year >=now(year)
Now all entrys with 0000-00-00 wont be selected. If i use OR the entrys from last year will be shown.
So thats my problem, is there any way i can change my table so i can have entries with only the year or only year and month and of course all together? I already considered get rid of the date-format and use simple INT with seperated columns for year, month and date. But i think i will have the same problem.
Sometimes i just want to do a capsuled select like
SELECT *
WHERE (date >= now AND year >= now(year))
OR date == "0000-00-00" (i know that this doesnt work)

If I understood your problem correctly, you could use this request:
WHERE (date >= now OR year > now(year))
There is probably a simpler way though, that would preserve your design, like initializing at January 1st (01-01) instead of 00-00

I think you can use this code:
$_SESSION['month'] = //set here your selected month
$_SESSION['year'] = //set here your selected year
SELECT * FROM table WHERE DATEPART(m,date) >= '".$_SESSION['month']."' AND DATEPART(yyyy,year) >= '".$_SESSION['year']."' AND date <> '0000-00-00'

Change your table structure format. Actually just allow for that field to have null value when not entered. By default it will be null then. You shouldn't be storing 0000-00-00 as a value for Date type field. I would rather leave it as null , or as suggested in some of previous answers, initialize it with some other date. It would be much easier to manipulate with database then.

the problem is that half of you write is not MySQL and your database schema is terrible...
You have the following problems:
column data date does not have the date data type.
To fix it, you need to add a cast to the select statement eg. cast(datecolumn as date)
select * from table where cast(datecolumn as date) >= '2014-01-10';
the way to use now date is using the now function.
select now(), date(now());
result> 2014-01-10 11:11:36, 2014-01-10
select * from table where cast(datecolumn as date) >= date(now());
Because your datecolumn is not a date (2014-00-00 is not a valid date), you need to use string manipulation to extract the year.
select substring('2014-01-01', 1,4)
result> 2014
select * from table where substring(datecolumn, 1,4) = year(now());
The comparassion operator is = and not ==
the select statement syntax looks like this (pay attention because you are missing the table in your statement)
select * from [Table] where [column] = condition ...
You probably need or instead of ands, therefore your query should look like this:
select * from FooTable where
cast(datecolumn as date) >= date(now())
or substring(datecolumn, 1,4) >= year(now())
or datecolumn = '0000-00-00'
You should use something like phpmyAdmin or mySQL workbench to test your sql queries before try to use them on php, java or whatever is your programing language.

Related

SQL query to select data between dates does not show last date

im using a query to get data between dates but for some reason it does not pull the data of the last date selected here is my query:
SELECT * FROM order WHERE status = "completed" AND orderdate >= ? AND orderdate <= ? ORDER BY orderid DESC
Im using is equal to or less then... but still?
what am i doing wrong ?
SELECT * FROM order WHERE status = "completed" AND date(orderdate) >= date(?) AND date(orderdate) <= date(?) ORDER BY orderid DESC
It happened with me also, but in my case instead of passing a date I was querying using a datetime variable, Please make sure you are querying with date variable only.
Make sure that orderdate is date as well as your query parameter is also date, or use appropriate function to convert them in date, than query.
Your dates are actually datetimes - so you are actually, in the case of the upperbound, saying "12 midnight" on whichever date you choose. Hence, if it tries to test a value at say 10am in the morning, it fails as being outside the range.
Either set the upperbound date one day forward, or explicitly only test the date part of the datetime...

Sql - find if date is between two dates

I have a field of FromDate and a field of ToDate.
I am looking for the rows that today is between the "from" and "to"
select * from job
where job.type='manager'
and '2014-01-22' between job.FromDate and job.ToDate
The query does not throw an exception , and it even returns some rows. But it isn't right- the rows it returns do not have the dates I am looking for.
P.S. the date format I am using is the correct one for my DB.
Try this
select * from job
where job.type='manager'
and job.FromDate <= '2014-01-22' and job.ToDate >= '2014-01-22'
Comparing dates is often tricky, especially if the values are stored as datetime and not date. The time components can affect the comparison. Another possibility is that ToDate is NULL for the most recent records. Here is one way to fix this:
select *
from job
where job.type ='manager' and
date('2014-01-22') between date(job.FromDate) and date(coalesce(job.ToDate, '2099-12-31'))
However, the use of the function on the columns can make the query less efficient. Instead, you might try:
select *
from job
where job.type ='manager' and
job.FromDate < '2014-01-23' and
(job.ToDate >= '2014-01-22' or job.ToDate is null);

mysql select with priority of 3 filelds in a query

my table and fields are like these:
i must find $sy<year<$ey then it must filter only values by $sm<month<$em at last it must find $sd<day<$ed
i need to find records between dates for example like 2010/10/25 , 2010/10/10
at first i tried :
SELECT SUM(barname) allin,SUM(rooz) allhoghogh,user_id FROM work_result
WHERE (`year`>='$sy' and `month`>='$sm' and `day`>='$sd') and (`year`<='$ey' and `month`<='$em' and `day`<='$ed') group by user_id ;
but it cant find records for dates like e like 2010/10/25 , 2010/10/28
than i tried
SELECT * FROM work_result as t1 join work_result as t2 on t1.year<='$sy' and t2.year>='$ey' and t1.month<='$em' and t2.month>='$sm' and t1.day<='$ed' and t2.day>='$sd' WHERE 1 group by t1.wrid
this isnt usful in my case!
i need some thing like priority select first select all between years than month and than day!!
other way is convert mysql records to timestamp by year and month and day and compare it by input date but UNIX_TIMESTAMP('year-month-day 00:00:00') dont worked correct for me.
i used it like :
SELECT * FROM `work_result` WHERE UNIX_TIMESTAMP('year-month-day 00:00:00')>1238921453
If convert to timestamp didn't work for you what about use date_format to convert:
SELECT *
FROM `work_result`
WHERE date_format(concat(year,'-',month,'-',day), '%Y-%m-%d') >
DATE_FORMAT(FROM_UNIXTIME(`yourDateGoesHere`), '%Y-%m-%d')

how to get the data using from date and to date in sql server?

i need to retreive data from database with the condition from date to to date using between query,
my query is,
select * from Master where Date between '01-08-2013' and '30-08-2013'
but it retreive all data from the table...
i need only data with in that date..
i tried another one like,
select * from PatientMaster where EntryDate >= '01-08-2013' and EntryDate<= '30-08-2013'
how its posible..
whats wrong with my query...
sorry im very bad in english...
thank you in advance...
A date string has the syntax YYYY-MM-DD and not DD-MM-YYYY
select * from Master
where `Date` between '2013-08-01' and '2013-08-30'
for that you can use
select * from Master where Date >='01-08-2013' and dateadd(dd,1,'30-08-2013')
You have to convert your strings to dates. This page shows you how to do it in mysql, which is what you have tagged. For sql server, which is in your subject line, use this page.
Then you do a slight modification of your 2nd attempt. Instead of
and EntryDate <= the end date
you want
and EntryDate < the day after the end date
That takes care of any time components. It might not matter in your case, but it's a good habit to get into.
You'll be looking for an query that works with your format? (dd-mm-yy)
CAST to the desired format!
http://www.w3schools.com/sql/func_convert.asp
105 = dd-mm-yy
SELECT * FROM Master
WHERE CONVERT(date, Date, 105) BETWEEN '01-08-13' and '30-08-13'
Be conscious with regards of the choice of data type for date Columns,
with or without time, day or year first etc. and please do not use varchar
for dates...
know that it CAN be confusing to call a date column for only Date...
be consistent with high/lower case.

How to use where clause in separate datetime(year,month,day)

http://upic.me/i/hq/capture.png
http://upic.me/i/3g/capture.png
I have the table that divide datetime to single field and set these field to index.
i would to use where clause in date range ex. between 2010/06/21 to 2011/05/15
I try to use
where concat_ws('-',year,month,day) between '2010/06/21' and '2011/05/15'
it's work because I use concat function to adjust these field like ordinary datetime
but it not use index and query slowly.This table has 3 million record
if would to use index I try to this query
where
year = '2011'
and month between 05 and 06
and day between 21 and 15
It almost work but in last line
day between 21 and 15
I can't use this condition
I try to solve this problem but I can't find it and change structer table
I'm looking for answer
thank you
Now I can OR operation for query thank for your answer
In another case if would to find 2009/08/20 to 2011/04/15 It's use longer query and make confusion.Has someone got idea?
If it's a datestamp type, you can just use the where/between clause directly. I would consider switching to that, it's quite faster than a varchar with a custom date format.
WHERE yourdate BETWEEN "2011-05-01" AND "2011-06-15"
Although checking ranges may work for single months, you will find if you're querying between several months to have some margin of error because, if you think about it, you're selecting more than you may necessarily want. Using Datestamp will fix performance and usability issues arising from storing the date in a custom varchar.
Here are the two queries to convert your times around if you're interested:
ALTER TABLE `yourtable` ADD `newdate` DATE NOT NULL;
UPDATE `yourtable` SET `newdate` = STR_TO_DATE(`olddate`, '%Y/%m/%d');
Just change "yourtable", "newdate", and "olddate" to your table's name, the new date column name, and the old datestamp column names respectively.
If you can't change the table structure, you could use something like the following:
WHERE year = '2011'
AND ((month = '05' AND day >= 21) OR (month = '06' AND day <= '15'))
(At least, I think that query does what you want in your specific case. But for e.g. a longer span of time, you'd have to think about the query again, and I suspect queries like this could become a pain to maintain)
UPDATE for the updated requirement
The principle remains the same, only the query becomes more complex. For the range of 2009/08/20 to 2011/04/15 it might look like this:
WHERE year = '2009' AND (month = '08' AND day >= '20' OR month BETWEEN '09' AND '12')
OR year = '2010'
OR year = '2011' AND (month BETWEEN '01' AND '03' OR month = '04' AND day <= '15')
where year = 2011
and (month between 5 and 6) and (day > 20 or day < 16)
You where seperating days and month whereas you must keep them together
parentheses must be set ...
Mike
It is important that you use OR otherwise it is nonsense