tags:

views:

62

answers:

3

I need a proper way to write a simple WHERE, AND, OR statement. This one doesn't work:

SELECT `content` 
  FROM `bx_wall_events` 
 WHERE `type` = 'wall_common_text' 
    OR `type` = 'wall_common_fb' 
    OR `type`= 'wall_common_tw' 
   AND `owner_id`='{$iId}' 
ORDER BY `date` DESC 
   LIMIT 1
A: 

"SELECT content FROM bx_wall_events WHERE ((type= 'wall_common_text') || (type= 'wall_common_fb') || (type= 'wall_common_tw')) AND owner_id='{$iId}' ORDER BY date DESC LIMIT 1"

Mick
Double pipes in SQL is string concatenation...
OMG Ponies
In MySQL by default, || is a logical OR operator. With PIPES_AS_CONCAT enabled, || is string concatenation (see http://dev.mysql.com/doc/refman/5.1/en/operator-precedence.html)
martin clayton
@martin clayton: Didn't know that, but I did know that if you enable strict SQL then double pipes are for string concatenation...
OMG Ponies
@OMG Ponies - absolutely. One of those little MySQL quirks...
martin clayton
+5  A: 

It's a valid statement, but I imagine the issue is the ORs aren't being interpreted like you'd expect. Use the IN syntax instead:

  SELECT content
    FROM bx_wall_events
   WHERE `type` IN ('wall_common_text', 'wall_common_fb', 'wall_common_tw')
     AND `owner_id` = '{$iId}' 
ORDER BY `date` DESC 
   LIMIT 1

I removed the backticks in certain spots because they're only necessary for escaping table & column names that are using MySQL reserved keywords.

The way this:

WHERE `type` = 'wall_common_text' 
   OR `type` = 'wall_common_fb' 
   OR `type`= 'wall_common_tw' 
  AND `owner_id`='{$iId}' 

...is evaluating is:

WHERE (`type` = 'wall_common_text')
   OR (`type` = 'wall_common_fb')
   OR (`type`= 'wall_common_tw' AND `owner_id`='{$iId}')
OMG Ponies
You can also just place parentheses around the ORs to separate them from the AND, but I do agree this is the way to go here.
Michael Madsen
@Michael Madsen: You can, but `IN` is more maintainable--miss or misplace one bracket, and the query can be valid but won't return correct data. Miss a bracket on the `IN`, and you're guaranteed a syntax error.
OMG Ponies
A: 

Found a great solution using the IN

"SELECT `content` 
FROM `bx_wall_events` 
WHERE `owner_id`='{$iId}' 
AND `type`
IN ('wall_common_text', 'wall_common_fb', 'wall_common_tw') 
ORDER BY `date` 
DESC LIMIT 1"
whatshakin