I am trying to search for studentID within a date range.
I only have one date in my database, therfore i only want the users to input one date, rather than having them input a start date and an end date for:
WHERE timeStamp BETWEEN startDate AND endDate
So i am trying this...
SELECT * FROM scansTable
INNER JOIN registeredUsers ON scansTable.studentID = registeredUsers.id
INNER JOIN labSession ON scansTable.labSessionID = labSession.id
INNER JOIN staffTable ON labSession.lecturer = staffTable.id
INNER JOIN unitTable ON labSession.unit = unitTable.id
WHERE studentID = '10'
AND labSession.StartTimeStamp BETWEEN '2011 -05 -30'+00:00:00
AND '2011 -05 -30'+23:59:59;
But it is not returning anything when i know for sure there is a student of id 10 and that date range in the database
Am i doing the +00:00:00 wrong??
thanks
Remove the spaces and plus symbols:
BETWEEN '2011-05-30 00:00:00' AND '2011-05-30 23:59:59'
It seems you are using something like '2011 -05 -30'+00:00:00, where you should use '2011-05-30 00:00:00' (and make corresponsing changes to the second condition), because TIMESTAMP format (I assume this field is in this format) is YYYY-MM-DD HH:MM:SS.
Did it help? If not, give use the definition of the table plus the example row (at least both timestamp columns).
EDIT:
If you wanted to concatenate, you should have used CONCAT() function (see MySQL's documentation). It would look like this:
CONCAT('2011-05-30',' 00:00:00')
or, more meaningfully:
CONCAT_WS(' ','2011-05-30','00:00:00')
If you haven't changed the default date format, remove the + signs and the extra spaces.
labSession.StartTimeStamp BETWEEN '2011-05-30 00:00:00' AND '2011-05-30 23:59:59';
Also, I don't know if it's a byproduct of the copy/paste, but MySQL won't even run the query as-is. The time portion of your timestamp needs to be within the quotes.
between might not include that lower bound as an =
i believe it does include the upper bound as =, this might differ depending on the database.
Related
Been testing this over and over, and it fails at the date comparison.(item.id_type seems to work fine).
request.date has the datatype DATETIME.
SELECT request.id, request.date, request.total_price,
item.cod_GERFIP,item.price,item.name,request_item.quantity,
section.name AS section,user.firstname,user.lastname
FROM ((((`request_item`
INNER JOIN `request` ON request_item.id_request = request.id)
INNER JOIN `item` ON request_item.id_item = item.cod_GERFIP)
INNER JOIN `user` ON request.id_user = user.id)
INNER JOIN `section` ON user.section = section.id)
WHERE request.date >= '2019-01-09' AND request.date <= '2019-01-10'
AND item.id_type = '1'
ORDER BY request.date DESC
Just a guess, because you haven't explained what or how the query fails, but to my eyes this condition does not look correct:
request.date <= '2019-01-10'
It's a common mistake to expect a condition like this, when used a part of a range, to include all records where the date part of a datetime field is 2019-01-10. That is, if we have an example value in the database of 1 PM on the same day (2019-01-10 13:00:00), the expectation is this value will narrow to match the 2019-01-10 literal in the query, the two values will be equal, and so it will meet the condition.
It does work this way.
Instead, the 2019-01-10 literal in the query is widened to a full DateTime, that looks more like this: 2019-01-10 00:00:00.000. Now the 1 PM value from the table is compared with this full date time, and it fails the condition.
It's much more common for a date range to compare using an exclusive upper bound set for one day in the future:
request.date < '2019-01-11'
Alternatively, you may be tempted to do this:
request.date <= '2019-01-10 23:59:59.999'
It will even work most of the time. Just be warned that in the (rare) case of leap seconds, you can still end up with incorrect results that way.
You may also be tempted to do something like this:
convert(date,request.date) <= '2019-01-10'
This works, but it's not recommended because it prevents the use of any index you might have on the request.date field, and that cuts at the core of database performance.
Or maybe the problem is even simpler. With the start of range at 2019-01-09, maybe you wanted to get the records for exactly one day, and are surprised to see a few values from midnight on 2010-01-10. Again, the solution is you want an exclusive boundary at the top of the range:
request.date < '2019-01-10'
As a complete side note to the question, I'm a very sad the SQL BETWEEN operator is inclusive at both end of the range. This may make sense for numeric or string data, but for date values defining an exclusive upper bound for the BETWEEN operator would have made much more sense.
I have tried various recommendations based off of other posts with no avail.
I have a database scheme of records with a Created_Date Key, and Value would be 01/01/2017
I am trying to query the database records to give a returned count of How many records per month and which month those fall in line with.
With the following
SELECT SQL_NO_CACHE MONTH(`Created_Date`), COUNT(*)
FROM `CRM_Leads`
GROUP BY MONTH(`Created_Date`)
I return
MONTH(`Created_Date`) COUNT(*)
NULL 872
I have also tried almost all the variations on the following post
Count records for every month in a year
Any help would be appreciated.
assuming your created_date is a string of format ('dd-mm-yyyy') the you should convert as date with str_to_date
SELECT SQL_NO_CACHE MONTH(str_to_date(`Created_Date`, '%d/%m/%Y')), COUNT(*)
FROM `CRM_Leads`
GROUP BY MONTH(str_to_date(`Created_Date`, '%d/%m/%Y'))
For as long as you store date/time information as strings, you will have great difficulty using any date/time specific functions and features. If you are getting NULL from MONTH(str_to_date(Created_Date, '%d/%m/%Y')) then the str_to_date isn't converting the strings to dates and the most likely reason for this is the d m y "pattern" is not corrrect.
All you have old us about your "strings that might be dates" is that one of them looks like this: 01/01/2017. Now that could be DD/MM/YYYY or MM/DD/YYYY and we simply cannot tell which one is correct from the single value you have chosen to share with us. Look for any day value greater then 12 in your data e.g. 17/01/2017 ==> DD/MM/YYYY or 01/17/2017 ==> MM/DD/YYYY
Once you have made the choice of which pattern your "strings that might be dates" follow; apply that pattern in the str_to_date() function. You migh want to try a few different patterns to get the best one (and these are just 3 of many you could try):
# which pattern is best for you?
SELECT Created_Date
, str_to_date(`Created_Date`, '%d/%m/%Y') "d/m/y"
, str_to_date(`Created_Date`, '%m/%d/%Y') "m/d/y"
, str_to_date(`Created_Date`, '%Y-%m-%d') "y-m-d"
FROM `CRM_Leads`
You will not have success with your group by query until you choose the most appropriate d m y pattern to apply in teh str_to_date function. Note here that you might also have a variety of patterns in your data, in which case you have an even bigger problem to solve.
Once you have made the choice of which pattern your "strings that might be dates" follow; apply that pattern in the str_to_date() function and ONLY THEN your group by query will work.
SELECT * FROM `siparisler` WHERE `cafe_id` = 3 AND DATE_FORMAT(tarih,'%Y-%m-%d') BETWEEN 2017-08-01 AND 2017-08-06
My dates are listed like this on my table (tarih) 2017-02-22 15:28:33
so I want to retrieve data when cafe_id is 3 and tarih between those two dates.
But when I run this query I get zero results.
What may be the problem. I could not find any solution.
DATE_FORMAT() is used on a date data type. You don't need it. You only need the quotes around the constants:
SELECT s.*
FROM siparisler s
WHERE s.cafe_id = 3 AND
s.tarih >= '2017-08-01' AND
s.tarih < '2017-08-07'
Note that I changed the condition from BETWEEN to direct comparisons. This is on purpose. This logic will work regardless of whether tarih has a time component.
You missed to quote the date string literal. It should be
BETWEEN '2017-08-01' AND '2017-08-06'
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.
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