Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Join tables only where value not in table B

Tags:

sql

mysql

I am trying to join 2 tables and filter on a value not being present.

Table_Items: item_id, title, etc

Table_History: item_id, history_id, action, date

For each disc there are many possible actions (purchased,added,played,ripped,etc) each action creates a new row in table_history linked by item_id. The query I am looking for will return all discs which have not been ripped. My query returns too many rows, everything is returned because there is at least one entry in the history table for each item.

SELECT items.item_id, items.title AS Title, items.`author/creator`, history.action 
FROM items
LEFT JOIN history ON items.item_id = history.item_id
WHERE history.action NOT LIKE 'Ripped%' GROUP BY items.item_id ORDER BY title

I am using mySQL. Help would be appreciated! Thank you.

like image 395
James Avatar asked Sep 01 '11 20:09

James


People also ask

Can you join tables in the WHERE clause?

You join two tables by creating a relationship in the WHERE clause between at least one column from one table and at least one column from another. The join creates a temporary composite table where each pair of rows (one from each table) that satisfies the join condition is linked to form a single row.

How do I join two tables without conditions?

Using the “FROM Table1, Table2” Syntax One way to join two tables without a common column is to use an obsolete syntax for joining tables. With this syntax, we simply list the tables that we want to join in the FROM clause then use a WHERE clause to add joining conditions if necessary.

Which join return rows that don't match?

The JOIN or INNER JOIN does not return any non-matching rows at all. It returns only the rows that match in both of the tables you join. If you want to get any unmatched rows, you shouldn't use it. The LEFT JOIN and the RIGHT JOIN get you both matched and unmatched rows.

What is the type of join when joining tables without a WHERE clause?

A CROSS JOIN produces a result set in which every row in each table is joined to every row in the other table; this is also called a cartesian product. In MariaDB the CROSS keyword can be omitted, as it does nothing. Any JOIN without an ON clause is a CROSS JOIN.


1 Answers

Just add the action filter to the join and then test for null (anti-join) in the where

SELECT items.item_id, 
       items.title AS title, 
       items.`author/creator`, 
       history.ACTION 
FROM   items 
       LEFT JOIN history 
         ON items.item_id = history.item_id 
            AND history.ACTION LIKE 'Ripped%' 
WHERE  history.item_id IS NULL 
GROUP  BY items.item_id 
ORDER  BY title 

you could also do a not in

SELECT items.item_id, 
   items.title AS title, 
   items.`author/creator`, 
   history.ACTION 
FROM   items 
       LEFT JOIN history 
         ON items.item_id = history.item_id 
WHERE  history.item_id NOT IN (SELECT history.item_id 
                                      FROM   history 
                                      WHERE  history.ACTION LIKE 'Ripped%') 
GROUP  BY items.item_id 
ORDER  BY title 
like image 148
Conrad Frix Avatar answered Oct 30 '22 11:10

Conrad Frix