简体   繁体   中英

Error in SQL CASE in where statement during select

I have a query that selects 3 random items from database table but I need to apply some more logic to the query based on the value of a field in the query.

This is what I have so far hope it makes sense. Have not fully tested it yet figured I would run it through you guys first see if there is anything that jumps out.

SELECT ord.id, keyword, url, daily_max
  FROM orders AS ord
  LEFT JOIN product_tasks AS tsk ON tsk.id = ord.task_id
  LEFT JOIN product_groups AS grp ON grp.id = tsk.product_group
  WHERE (
    status = 'approved'  AND
    ord.total_actions_today < tsk.daily_max AND
    grp.id = 1 AND
    country_code = '$country' AND
    (   

        CASE WHEN daily_max >= 5 THEN last_displayed < (NOW() - INTERVAL 30 MINUTE)

        CASE WHEN daily_max >10 THEN last_displayed < (NOW() - INTERAVAL 5 MINUTE)

        ELSE last_displayed < (NOW() - INTERAVAL 60 MINUTE)
    )   
  )
  GROUP BY ord.id
  ORDER BY RAND()
  LIMIT 3

Just tested the query and as I suspected I have my syntax wrong so any help would be appreciated:

#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CASE WHEN daily_max >10 THEN last_displayed < (NOW() - INTERAVAL 5 MINUTE) ' at line 14

Edit - Fixed

(After several attempts + edits):

SELECT ord.id, keyword, url, daily_max
      FROM orders AS ord
      LEFT JOIN product_tasks AS tsk ON tsk.id = ord.task_id
      LEFT JOIN product_groups AS grp ON grp.id = tsk.product_group
      WHERE (
        status = 'approved'  AND
        ord.total_actions_today < tsk.daily_max AND
        grp.id = 1 AND
        country_code = 'us'
AND  last_displayed < 
    CASE WHEN (daily_max >= 5) THEN (NOW() - INTERVAL 30 MINUTE)
         WHEN (daily_max >10) THEN (NOW() - INTERVAL 5 MINUTE)
         ELSE (NOW() - INTERVAL 60 MINUTE)
    END
    )
      GROUP BY ord.id
      ORDER BY RAND()
      LIMIT 3

http://sqlfiddle.com/#!2/ac4499/1

Solved DOH missing ) in the where statement

Your structure of your WHERE was not correct. Try the following:

SELECT ord.id, keyword, url, daily_max
  FROM orders AS ord
  LEFT JOIN product_tasks AS tsk ON tsk.id = ord.task_id
  LEFT JOIN product_groups AS grp ON grp.id = tsk.product_group
  WHERE (
    status = 'approved'  AND
    ord.total_actions_today < tsk.daily_max AND
    grp.id = 1 AND
    country_code = '$country' AND
    (   

        CASE WHEN daily_max >10 THEN (NOW() - INTERAVAL 5 MINUTE)
             WHEN daily_max >= 5 THEN (NOW() - INTERVAL 30 MINUTE)
             ELSE (NOW() - INTERAVAL 60 MINUTE)
        END > last_displayed
    )   

  )
  GROUP BY ord.id
  ORDER BY RAND()
  LIMIT 3

Move the last_displayed out of the CASE, such that it is compared to a single value as projected out of the CASE statement:

WHERE...
AND  last_displayed < 
    CASE WHEN (daily_max >= 5) THEN (NOW() - INTERVAL 30 MINUTE)
         WHEN (daily_max >10) THEN (NOW() - INTERVAL 5 MINUTE)
         ELSE (NOW() - INTERVAL 60 MINUTE)
    END;

Also note a couple of typos - INTERVAL not INTERAVAL , and just one CASE is required.

SqlFiddle here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM