如何在SQL中的两个表之间选择不匹配的行?

时间:2019-03-08 03:09:20

标签: sql sql-server join

我有两个表t1和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

我需要像这样在t1中不存在的国家/地区返回一个表:

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

这似乎很简单,但我无法解决。我尝试过:

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

我查看了堆栈溢出中的几个“不存在”问题,但是由于在t1和t2之间的公共列比示例中的列多,因此响应不起作用。有人可以向我指出正确的方向,或向我显示类似问题的链接吗?

3 个答案:

答案 0 :(得分:2)

我们可以尝试通过使用动态日历表来处理此问题:

    Date mgStringToDate(String mgString, String separator = "/") {

        if(mgString){
            Locale locale = Locale.getDefault(Locale.Category.FORMAT);
            Chronology chrono = MinguoChronology.INSTANCE;
            DateTimeFormatter df = new DateTimeFormatterBuilder().parseLenient()
                    .appendPattern("yyy${separator}MM${separator}dd").toFormatter().withChronology(chrono)
                    .withDecimalStyle(DecimalStyle.of(locale));
            TemporalAccessor temporal = df.parse(mgString);
            ChronoLocalDate cDate = chrono.date(temporal);
            Date date = Date.from(LocalDate.from(cDate).atStartOfDay(ZoneId.systemDefault()).toInstant());
            return date
        }else{
            return null
        }
    }

Demo

答案 1 :(得分:0)

您可以使用plants来生成countiresNOT EXISTS的所有可能组合,然后使用带有相关子查询的t2条件来过滤出{ {1}}:

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
)

答案 2 :(得分:0)

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