0

I've spent a lot of time searching for an answer to this problem online but I can't seem to come up with anything useful.

I'm pretty new to mySQL so I have a limited enough knowledge.

I have a table events with 6 columns: id, event_name, event_date, event_close_time, event_link, and event_image.

I'm trying to select everything from the database where the event_close_time is < current time if the event is on today and select all the other events in the future.

What I came up with is:

SELECT * FROM `events` 
WHERE `event_date` >= 'todays_date'
AND `event_close_time` >  'current_time'
ORDER BY `event_date`

but this doesn't do exactly what I want it to do. It returns all events that are on today or in the future as long as their closing time is earlier then the current time.

It's important that I do it in 1 query because the ORDER BY clause at the end allows me to sort the events into the order I want to use in my web application.

Could anyone point out the adjustments I need to make to get the desired result?

2
  • First, don't you mean event_close_time > current time? You should not be storing dates and times separately, but use timestamp columns so it's a single comparison. How are the dates/times currently stored? Commented Jul 7, 2013 at 3:03
  • Thanks Jim, your right. Simple mistake, thats sleep deprivation for you. Commented Jul 7, 2013 at 3:14

2 Answers 2

1

You should do this with one select and the correct where clause:

SELECT *
FROM `events` 
WHERE (event_date = CURDATE() AND event_close_time < CURTIME()) or
      (event_date > CURDATE())
ORDER BY `event_date`;

Implementing or logic by using union or union all is a bad habit to get into. For one thing, it requires scanning the events table twice, once for each condition. The single where only scans the table once.

Sign up to request clarification or add additional context in comments.

3 Comments

That's where you are wrong. Union queries are often times better optimized because an OR in the where clause automatically causes a FULL TABLE SCAN in MySQL because it cannot use indexes when you have the OR, whereas a union query only has to run 2 separate, more optimized queries that CAN use indexes. This can be verified by running an explain query. If you try this for yourself, I guarantee the UNION query will be faster if there is any significant amount of data in the table.
@Seth . . . I stand by my comment. Using union or union all is a bad habit when you mean or. Using union/union all intentionally for performance reasons (such as using indexes), that is fine. But using it to mean or just complicates queries, makes them hard to maintain, and is typically unnecessary.
Sure, it complicates queries.Best practices are often times harder. If it's a bad habit, then why? Writing a UNION query that only looks at a tiny fraction of a table versus an OR query that causes a full table scan is obviously better for a number of reasons. The OR query may work fine for a lot of cases, but if you want to build applications designed to scale, any OR queries will be the first ones to start having performance issues once you start having more data in the tables. I know this because I designed and maintained an enterprise application that supports hundreds of concurrent users.
0

How about this?

SELECT *
FROM events
WHERE event_date = CURDATE()
AND event_close_time < CURTIME()
UNION ALL 
SELECT * 
FROM events 
WHERE event_date > CURDATE()
ORDER BY event_date

This could also be accomplished with an OR instead of the UNION ALL, but I have found that UNIONS tend to be more efficient because ORs cause indexes not to be used (at least in MySQL).

1 Comment

Thanks a lot Seth. That completely solves my problem! Also Jim was right about the 'event_close_time > current time'.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.