1

我有两个 sql 语句,我希望通过自然连接加入,但由于某种原因,以下给了我一个错误:

(select city_name
from city
left join country
on country.country_name=city.country_name
where country.continent='Europe'
and city.iscapitol='yes')

natural join

(select city_name
from city
left join country
on country.country_name=city.country_name
where country.continent='Europe'
and city.iscapitol='no';)

我正在使用 oracle 平台,它抛出的错误是:

natural join
*
ERROR at line 7:
ORA-00933: SQL command not properly ended

出现此错误的原因是什么?任何帮助将不胜感激。

4

2 回答 2

1
select * from (
(select city_name
from city
left join country
on country.country_name=city.country_name
where country.continent='Europe'
and city.iscapitol='yes')

natural join

(select city_name
from city
left join country
on country.country_name=city.country_name
where country.continent='Europe'
and city.iscapitol='no'))

我已经删除;并添加了外部查询。我还建议natural join用明确的条件替换join

with eurcities as (select city_name, iscapitol, country_name from city
      left join country on country.country_name=city.country_name
      where country.continent='Europe')
select c1.city_name, c2.city_name, c1.country_name 
  from eurcities c1 inner join eurcities c2 on (c1.country_name = c2.country_name) 
  where c1.iscapitol = 'yes' and c2.iscapitol = 'no';

没有with它看起来像:

select c1.city_name, c2.city_name, c1.country_name 
  from (select city_name, iscapitol, country_name from city
            left join country on country.country_name=city.country_name
            where country.continent='Europe') c1 
    inner join (select city_name, iscapitol, country_name from city
            left join country on country.country_name=city.country_name
            where country.continent='Europe') c2 
    on (c1.country_name = c2.country_name) 
  where c1.iscapitol = 'yes' and c2.iscapitol = 'no';
于 2016-11-18T20:21:00.937 回答
0

首先,忘却natural join。这是一个等待发生的错误。不显示join代码中的键是危险的。忽略声明的外键关系是不明智的。依赖命名约定是很尴尬的。

您可以使用using. 所以,修正语法,这看起来像:

select *
from (select city_name
      from city left join
           country
           on country.country_name = city.country_name
     where country.continent='Europe' and city.iscapitol = 'yes'
    ) cc join
    (select city_name
     from city left join
          country
          on country.country_name = city.country_name
     where country.continent = 'Europe' and city.iscapitol='no'
    ) cnc
    using (city_name);

请注意,left join子查询中的 s 是不必要的。

也就是说,我认为聚合是一种更简单的查询方法:

      select city_name
      from city join
           country
           on country.country_name = city.country_name
      where country.continent = 'Europe'
      having sum(case when city.iscapitol = 'yes' then 1 else 0 end) > 0 and
             sum(case when city.iscapitol = 'no' then 1 else 0 end) > 0;

或者,如果iscapitol[sic] 仅采用两个值,则可以将其用于having子句:

      having min(city.iscapitol) <> max(city.iscapitol)
于 2016-11-18T20:48:40.143 回答