views:

754

answers:

2

I'm not sure if I'm missing something really obvious, but I keep getting a syntax error on this query. Even if I AM missing something obvious, I'd like to know if there is a smarter way of getting what I'm after.

Basically, the query asks for any rows tied to a user with a start_date between Monday and Friday. That works great. But then I added a conditional query in case there are any rows for that Saturday or Sunday. Note that the conditional query is checking for ANY users with a Saturday or Sunday, not the user in the main query:

SELECT user_id,
DATE_FORMAT(DATE(shift_start),'%m/%d/%Y') date, 
TIME_FORMAT(TIME(shift_start), '%h:%i %p') start,
TIME_FORMAT(TIME(shift_end), '%h:%i %p') end,
title   
FROM shifts
WHERE user_id = '$user_id'
AND DATE(shift_start) BETWEEN
DATE_SUB(DATE(NOW()), INTERVAL WEEKDAY(NOW()) DAY) AND
DATE_ADD(DATE(NOW()), INTERVAL 
 (SELECT
 IF( 
 COUNT(*) FROM shifts
 WHERE DATE(shift_start) BETWEEN
 DATE_ADD(DATE(NOW()), INTERVAL 5 - WEEKDAY(NOW()) DAY) AND
 DATE_ADD(DATE(NOW()), INTERVAL 6 - WEEKDAY(NOW()) DAY),
6, 4)) - WEEKDAY(NOW()) DAY)
ORDER BY shift_start

I'm actually pretty proud of how it works before it messes up with the IF part, but again, if there is an obviously better way doing this, I'm all ears.

Oh, and when this gets ironed out, the "Now()" will be replaced with a date variable set up in the php script (passed to it via GET).

Thanks!


Awesome job, benlumey. Here's what worked:

SELECT user_id,
DATE_FORMAT(DATE(shift_start),'%m/%d/%Y') date, 
TIME_FORMAT(TIME(shift_start), '%h:%i %p') start,
TIME_FORMAT(TIME(shift_end), '%h:%i %p') end,
title   
FROM shifts
WHERE user_id = '$user_id'
AND DATE(shift_start) BETWEEN
DATE_SUB(DATE(NOW()), INTERVAL WEEKDAY(NOW()) DAY) AND
DATE_ADD(DATE(NOW()), INTERVAL 
 (SELECT
 IF(COUNT(*),6,4) 
 FROM shifts
 WHERE DATE(shift_start) BETWEEN
 DATE_ADD(DATE(NOW()), INTERVAL 5 - WEEKDAY(NOW()) DAY) AND
 DATE_ADD(DATE(NOW()), INTERVAL 6 - WEEKDAY(NOW()) DAY))
            - WEEKDAY(NOW()) DAY)
ORDER BY shift_start
+2  A: 

Try this subquery:

(SELECT 
    IF(COUNT(*) > 0, 6, 4)) - WEEKDAY(NOW()) DAY) 
    FROM shifts 
    WHERE DATE(shift_start) BETWEEN
    DATE_ADD(DATE(NOW()), INTERVAL 5 - WEEKDAY(NOW()) DAY) AND
    DATE_ADD(DATE(NOW()), INTERVAL 6 - WEEKDAY(NOW()) DAY)

Two things I've done

  • made it look like a normal query, the from and where can't go inside the if as far as i'm aware.
  • Put a condition in the if, don't think mysql will automatically take 0 as false and >0 as true.
benlumley
If the from and where can't go inside the if(), that would be really dissapointing, but would explain everything! As far as your second point, 0 as false is exactly what the [if statement][1] does, that's why I was eager to use it. [1]:[http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html#function_if]
Anthony
Also, I am really in the dark on how your subquery would produce the desired result. What is the Count counting and what is the if iffing? Sorry to sound weird. Basically I mean, the if function seems to be isolated from the sub-query in such a way that I don't see how it is being triggered from the query itself. Again, I'm here to learn.
Anthony
And you win the big prize! I'll post how I did it (the really simple fix based on your answer) as a comment.
Anthony
glad it helped.
benlumley
+1  A: 

this falls apart around here:

    (SELECT
    IF( 
       COUNT(*) FROM shifts
    WHERE DATE(shift_start) BETWEEN

The count statement won't work.

What are you trying to do? You need a clear statement of what you are trying to accomplish here.

This is my swag at it:

 (SELECT
    IF( 
      (select COUNT(*) FROM shifts
       WHERE DATE(shift_start) BETWEEN
       DATE_ADD(DATE(NOW()), INTERVAL 5 - WEEKDAY(NOW()) DAY) AND
       DATE_ADD(DATE(NOW()), INTERVAL 6 - WEEKDAY(NOW()) DAY))>0,6,4)
 ) - WEEKDAY(NOW()) DAY

But without knowing what you are trying to do I'm not sure.

Dennis Baker
"SELECT IF(COUNT(*) FROM shifts" doesn't look right to me
too much php
Doing a Select if Select crossed my mind, but seemed really funky, not to mention it sounds like it would cause a serious bottleneck. But that's why I come here, to learn. So the idea is this (let me know if this is still unclear): The query is pulling all the user's weekly shifts. On most weeks, weekends are free, but occasionaly, and without any real pre-determined pattern, there are weekend shifts. If there are NO weekend shifts for ANYONE, the output is going to be a M-F schedule. BUT if there ARE scheduled shifts for ANYONE, the output is a M-Sun schedule.
Anthony
So, the query is basically saying "if the count of shifts on this week's saturday or sunday = 0, use 4 (thus making the end of the week Friday), but otherwise make it 6 (making the end of the week Sunday). So the Count(*) is to produce the 0 or Null that will trigger the IF() function to use the 4, not the 6 for the Date_ADD
Anthony