简体   繁体   中英

MySQL: How to Remove One Row of a Multi-Row Record Based on Column

If I have two tables that I'm joining and I write the most simple query possible like this:

SELECT *
FROM t1
LEFT JOIN t2 ON t1.id = t2.id

There are a few records who have multiple rows per ID because they have multiple employers, so t1 looks like this:

ID         Name         Employer
12345      Jerry        Comedy Cellar
12345      Jerry        NBC
12348      Elaine       Pendant Publishing
12346      George       Real Estate
12346      George       Yankees
12346      George       NBC
12347      Kramer       Kramerica Industries

t2 is linked with the similar IDs but with some activities that I'd like to see -- hence the SELECT * above. Though I don't want multiple rows to return if the Employer column is "NBC" -- but everything else is good.

The only other thing that matters here is that t2 is smaller than t1 , because t1 is everybody and t2 are only from people who did particular activities -- so some of the matches won't return anything from t2 , but I would still like them to be returned, hence the LEFT JOIN .

If I write the query like this:

SELECT *
FROM t1
LEFT JOIN t2 ON t1.id = t2.id
WHERE Employer <> "NBC"

Then it removes Jerry and George completely -- when really all I want is for the NBC row to not be returned, but to return any other rows that are associated with them.

How can I write the query while joining t1 with t2 to return each row except for the NBC ones? The ideal output would be all of the rows from t1 regardless if they match up with all of t2 except removing all of the rows with "NBC" as the employer in the return file. Basically the ideal here is to return the JOINs where they fit, but regardless remove the entire row for anybody with "NBC" as employer without removing their other rows.

The more I write about it, it seems like I should potentially just run a query prior to my JOIN to delete all the rows in t1 who have "NBC" as their employer and then run the normal query.

Basic subset filtering

You can filter either of the two merged (joined) subsets by extending the ON clause.

SELECT    *
FROM      t1
LEFT JOIN t2
       ON t1.ID = t2.ID
      AND t2.Employer != 'NBC'

If you get null values now, and you don't want them, you'd add:

WHERE t2.Employer IS NOT NULL

extended logic:

SELECT    *
FROM      t1
LEFT JOIN t2
       ON (t1.ID = t2.ID AND t2.Employer != 'NBC')
       OR (t2.ID = t2.ID AND t2.Employer IS NULL)

Using UNION

Basically, JOIN is for horizontal linking and UNION does vertical linking of datasets.

It merges to resultsets: the first without NBC, and the second (which is basically an OUTER JOIN ), adds everyone in t1 which is not part of t2.

SELECT    *
FROM      t1
LEFT JOIN t2
       ON t1.ID = t2.ID
      AND t2.Employer != 'NBC'
UNION
SELECT    *
FROM      t1
LEFT JOIN t2
       ON t1.ID = t2.ID
      AND t2.Employer IS NULL

String manipulation in the resultset

If you just want to remove NBC as a string, here is a workaround:

SELECT
    t1.*,
    IF (t2.Employer = 'NBC', NULL, t2.Employer) AS Employer
FROM t1
LEFT JOIN t2
    ON t1.id = t2.id

This basically replaces "NBC" by NULL

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