简体   繁体   中英

How to select rows with no match between two tables in SQL?

I have two tables t1 and t2

t1

plant  country    cost
------------------------
apple  usa        1
apple  uk         1
potato sudan      3
potato india      3
potato china      3
apple  usa        2
apple  uk         2


t2

country
--------
usa
uk
egypt
sudan
india
china

I need to return a table for countries that do not exist in t1 like so:

plant  country    cost
------------------------
apple  egypt      1
apple  sudan      1
apple  india      1
apple  china      1
apple  egypt      2
apple  sudan      2
apple  india      2
apple  china      2
potato usa        3
potato uk         3
potato egypt      3

This seems so easy but I cannot solve it. I tried:

select t1.plant, t2.country, t1.cost
from t1
right outer join t1 on t1.country = t2.country
where t2 is null
group by t1.plant, t2.country, t1.cost

I looked at several 'not exist' questions in stack overflow but the responses did not work because there were more columns in common between t1 and t2 than in my example. Could someone kindly point me in the right direction or show me a link to a similar problem?

We can try handling this via the use of an on-the-fly calendar table:

WITH cte AS (
    SELECT DISTINCT t1.plant, t2.country, t1.cost
    FROM t1
    CROSS JOIN t2
)

SELECT
    a.plant,
    a.country,
    a.cost
FROM cte a
WHERE NOT EXISTS (SELECT 1 FROM t1 b
                  WHERE a.plant = b.plant AND
                        a.country = b.country AND
                        a.cost = b.cost);

Demo

You could use a CROSS JOIN to generate all possible combinations of plants and countires , then a NOT EXISTS condition with a correlated subquery to filter out those that exists in t2 :

select plants.plant, countries.country, plants.cost
from t2 countries
cross join (distinct plant, max(cost) cost from t1 group by plant) plants
where not exists (
    select 1 from t1 where t1.country = countries.country
)
SELECT t.plant, t2.country, t.cost
FROM(
SELECT DISTINCT plant , cost
FROM t1)t
CROSS JOIN t2
LEFT JOIN t1 ON t1.plant = t.plant and t1.country = t2.country AND t.cost = t1.cost
WHERE t1.plant IS NULL AND t1.country IS NULL AND t1.cost is 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