MySQL Select Dates in the Past: Problem with MAX and GROUP BY - mysql

So, the query I'm trying to make looks like this right now:
SELECT `jid`, MAX(`start`) as `start` FROM `dates` WHERE `start` < NOW() GROUP BY `jid`
The table dates basically holds a DATETIME value start associated with a job.
As you probably guessed, jid is the id of a job, stored in another table.
A job can have many dates
What I'm trying to accomplish is to find out what jobs have all their start dates in the past.
My thought was to select the highest values of the start dates, grouped by jid and if they were in the past, it would imply that all other dates associated with the same job are also in the past.
This query isn't working because it's checking for start dates in the past and then selecting the highest of those. This doesn't exclude the possibility of another date for the same job, lying in the future.
I have no idea how I could proceed now. Any help or clue is appreciated.
Cheers - Tom

You have to use HAVING :
SELECT jid, MAX(start) as start
FROM dates
GROUP BY jid
HAVING MAX(start) < NOW();
HAVING acts a bit like WHERE. It filters out the rows after they were selected. Usually (and actually, I can't think of any other case), you only use HAVING with aggregate functions.
(I hope you really inserted dates in the future in your table, though!)

Related

Between and is working fine in MySql but not in T-SQL

We had a project with backend MySQL which we recently migrated to SQL Server 2005.
A query like the one given below used to work fine when MySQL was used where as it is giving unexpected result.
select * from employees where joindate between '2013-05-01' and '2013-05-01'
here the starting and ending dates are same.
MySQL used to give the records of employees who joined on '2013-05-01'.
Where as T-SQL is giving the records of employees who joined on '2013-04-30'
joindate column in the table has time part as well in which we are recording the exact time when the employee joined along with date.
Is there any work around for this problem. Please kindy let me know.
thanks,
dpchimmili.
MySQL used to give the records of employees who joined on '2013-05-01'. Where as T-SQL is giving the records of employees who joined on '2013-04-30'
that is how the different servers implemented the between function differently: for as mySQL includes all dates between and with the same date, T-sql only includes the dates between those dates and not the dates itself.
use Where statements as work around WHERE joindate >='2013-05-01' and joindate <= '2013-05-01' or jsut WHERE joindate ='2013-05-01'
You can use BETWEEN with TSQL if you just cast the value to a DATE.
select * from employees
where CONVERT(DATE, joindate)
between '2013-05-01' and '2013-05-01'
Better though is to check if the date is less than the next date, since that avoids a calculation per row and will hit indexes better;
select * from employees
where joindate>='2013-05-01'
and joindate<DATEADD(day,1,'2013-05-01')
An SQLfiddle to test with.

Two date columns, one date. How can I get the data?

I have the following problem:
In mysql I have a table which contains two date columns start_date and end_date. The date format is yyyy-mm-dd. What I am trying to do is to get all data from all the rows where a specific date, lets say '2012-03-05' mateches one of these date columns or are something in between.
How can I create a good sql-query that gets the data needed? I've checked on the between statement but I don't really know if that's the best way to go. I guess this is generally a simple task but I just can't figure a good query out.
Thanks.
SELECT * FROM table WHERE start_date <= '2012-02-29' AND end_date >= '2012-02-29';
Should do it.
This is a very common way to structure your tables with ranges of dates, especially in temporal database designs. It lets you perform range-based queries very efficiently, assuming that indexes on both columns exist. You query the data like this:
select *
from mytable t
where t.start_date <= #desired_date and t.endDate > #desired_date
#desired_date is the date for which you would like to query, e.g. '2012-03-05'.
Note the <= on one side and > on the other side, without =. This is done to ensure that the from-to ranges define non-overlapping intervals.
Not sure, try something like this:
SELECT
*
FROM
mytable
WHERE
'2012-03-05' BETWEEN start_date AND end_date
SELECT * FROM mytable
WHERE '2012-03-05' BETWEEN start_date AND end_date;

Mysql get things after certain date

So, I have a database table holding tickets. One of the fields is "availableUntil".
when I make the database call to get tickets, I want to be able to exclude those tickets who's date has already been passed relative to the current date.
Anyone know of a way to do this?
SELECT blablabla... WHERE availableUntil >= CURRENT_TIMESTAMP
SELECT [what_you_want] FROM your_base WHERE availableUntil > CURRENT_DATE();

storing dates in mysql

Is it better to store dates in mysql in three columns or use just one column. Which one is faster. Also, if I just want to do inserts with todays date in format dd/mm/yy , how do I do that. and also how do I do selects with that. Also, lets say if I wanted to get results for all the wednesdays, how do I do that or lets say one date 25th of all the months and years, how do i do that.
Thanks People.
I am using PHP with Apache and Mysql.
What are the drawbacks of using the structure that I am proposing. I can easily get all the 25th by using the date table and I can get all the days using another column for days. How much difference would be there in the terms of speed between my proposed solution and using a DATE table?
You will want to use a proper column type, such as DATE, DATETIME, or TIMESTAMP, depending on your needs. They are built specifically to handle dates, and can more easily perform other functions (adding, comparing, etc.) that would be difficult to perform on 3 separate columns.
Read this for more info.
DAYOFWEEK(date) will give you a numeric representation for the day. In your case, 4 = Wednesday. DAYOFMONTH(date) will work for finding all 25th days of the month.
DAYNAME(date) will return the name of the weekday for date
Also, if I just want to do inserts with todays date in format dd/mm/yy ,how do I do that.
Well it depends on the format your date is passed in through your
form but you are going to want to store your date in YYYY-mm-dd format.
INSERT INTO my_table (timefieldname) VALUES ( '$date' );
and also how do I do selects with that.
SELECT timefieldname FROM my_table;
//or you can format the date - this will give you month/day/year 01/01/2012
SELECT DATE_FORMAT(timefieldname, '%m/%d/%Y') FROM my_table;
Also, lets say if I wanted to get results for all the wednesdays,
SELECT timefieldname FROM my_table WHERE DAYNAME(timefieldname) = 'Wednesday';
How do I do that or lets say one date 25th of all the months and years, how do i do that.
SELECT timefieldname FROM my_table WHERE DAY(timefieldname) = '25';
You can free up having to pass dates from your codebase and let mysql insert them for you, provided they are time stamps:
ALTER TABLE tablename ADD `timefieldname` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ;
It's not much of a speed boost, but it does reduce your need to code and validate variables passed to the database.

MySql Query Grouping by Time

I am trying to create a report to understand the time-of-day that orders are being placed, so I need to sum and group them by time. For example, I would like a sum of all orders placed between 1 and 1:59, then the next row listing the sum of all orders between 2:00 and 2:59, etc. The field is a datetime variable, but for the life me I haven't been able to find the right query to do this. Any suggestions sending me down the right path would be greatly appreciated.
Thanks
If by luck it is mysql and by sum of orders you mean the number of orders and not the value amount:
select date_format(date_field, '%Y-%m-%d %H') as the_hour, count(*)
from my_table
group by the_hour
order by the_hour
This king of grouping (using a calculated field) will certainly not scale over time. If you really need to execute this specific GROUP BY/ORDER BY frequently, you should create an extra field (an UNSIGNED TINYINT field will suffice) storing the hour and place an INDEX on that column.
That is of course if your table is becoming quite big, if it is small (which cannot be stated in mere number of records because it is actually a matter of server configuration and capabilities as well) you won't probably notice much difference in performance.