简体   繁体   中英

MySQL Join: Omit ALL repeating rows IF one row meets a condition

Given the following example tables

TABLE_A
-----
 ID  
-----
  1
  2
  3
  4
  5

TABLE_B
---------------------------
 TABLE_A_ID        DETAIL
---------------------------
    1               val_x
    2               val_x
    2               val_y
    4               val_y
    5               val_other

I am doing a left join on these two tables and get the following output

-------------------------------
   TABLE_A_ID        DETAIL
-------------------------------
       1              val_x
       2              val_y
       2              val_x
       3              null
       4              val_y
       5              val_other

This is as I expect from a left join.

The problem I have is that I also want to remove rows that have DETAIL = val_y AND ALL rows that have a repeating TABLE_A_ID IF any row in the group has a DETAIL = val_y

So the output I need is;

-------------------------------
   TABLE_A_ID        DETAIL
-------------------------------
       1              val_x
       3              null
       5              val_other

I have tried using GROUP_BY TABLE_A_ID and HAVING DETAIL != val_y but that doesn't seem to work. I think for obvious reasons as GROUP_BY and HAVING are for aggregates and eliminating values that are less than or greater than right?

Is there a way to do this in MySQL or am I asking too much?

Note: These are EXAMPLE tables. They do not reflect a production system, so would appreciate no comments or answers outside the scope of the question and example - it just confuses things.

SELECT sub1.id table_a_id, sub1.detail
FROM (
    SELECT a.id, detail
    FROM table_a a
    LEFT JOIN table_b b on a.id = b.table_a_id) sub1
LEFT JOIN (
    SELECT DISTINCT table_a_id
    FROM table_b
    WHERE detail = 'val_y') sub2 
ON sub1.id = sub2.table_a_id
WHERE sub2.table_a_id IS NULL

The sub2 subquery finds all the IDs that meet your criteria for removal. This is then joined with the original query to filter out those IDs.

DEMO

You could use another LEFT JOIN to eliminate ids with a 'val_y' value;

SELECT a.id as table_a_id, b1.detail 
FROM table_a a
LEFT JOIN table_b b1 ON a.id = b1.table_a_id
LEFT JOIN table_b b2 ON a.id = b2.table_a_id AND b2.detail = 'val_y'
WHERE b2.detail IS NULL

An SQLfiddle to test with (updated with new sample data)

Try this:

   SELECT b.table_a_id, b.detail
   FROM table_a a JOIN table_b b ON a.id = b.id
   GROUP BY b.table_a_id
   HAVING COUNT( b.table_a_id ) == 1;

something like

select * from table_b where table_a_id not in (
    select TABLE_A_ID from TABLE_B where detail = 'val_y'
)

I think below will help you

Select a.ID ,b.Detail
From Table1 a 
LEFT OUTER JOIN (SELECT id ,count(*) from Table2 group by id having count(*) =1 ) b
ON a.id = b.ID

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