Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mysql query to select everything except

Tags:

sql

mysql

i have two mysql tables.

the first is called "chosen" and consists of id, user_id, and widget_id fields.

the other is called "widgets" and includes several things including widget_id.

i created a filter so that the user can either display widgets that he/she has chosen, or widgets that he/she hasn't chosen. for the ones he has chosen, i use this:

SELECT * 
  FROM widgets, chosen 
 WHERE chosen.user_id = $user_id 
   AND chosen.widget_id = widgets.widget_id

however, i can't figure out how to display the ones that he/she hasn't chosen. this doesn't work (displays everything):

SELECT * 
  FROM widgets, chosen 
 WHERE !(    chosen.user_id = $user_id 
         AND chosen.widget_id = widgets.widget_id)

how do i do this?

like image 545
vee Avatar asked Dec 10 '10 04:12

vee


2 Answers

Using NOT IN:

SELECT w.*
  FROM WIDGET w
 WHERE w.widget_id NOT IN (SELECT c.widget
                             FROM CHOSEN c
                            WHERE c.user_id = $user_id)

Using NOT EXISTS:

SELECT w.*
  FROM WIDGET w
 WHERE NOT EXISTS (SELECT NULL
                     FROM CHOSEN c
                    WHERE c.widget_id = w.widget_id 
                      AND c.user_id = $user_id)

LEFT JOIN/IS NULL:

   SELECT w.*
     FROM WIDGET w
LEFT JOIN CHOSEN c ON c.widget_id = w.widget
                  AND c.user_id = $user_id
    WHERE w.widget IS NULL

Performance:

If the columns compared (widget_id in either table) are not nullable, LEFT JOIN/IS NULL performs the best on MySQL. If the columns are nullable (the value could be NULL), NOT IN or NOT EXISTS perform better.

like image 59
OMG Ponies Avatar answered Sep 28 '22 23:09

OMG Ponies


Boolean logic: (ab)' is the same as a' + b'

SELECT * 
  FROM widgets, chosen 
 WHERE chosen.user_id <> $user_id 
         OR chosen.widget_id <> widgets.widget_id
like image 20
Elle H Avatar answered Sep 29 '22 01:09

Elle H