2016-11-18 4 views
0

У меня есть два SQL заявления, которые я хотел бы присоединиться через естественное соединение, но по какой-то причине следующее дает мне ошибку:Присоединяйтесь два выберите заявления 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';) 

Я использую оракула платформы и ошибка его составляет:

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

Какова будет причина появления этой ошибки? Любая помощь будет принята с благодарностью.

ответ

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'; 
+0

@Sal, пожалуйста, отредактируйте ваш вопрос и добавьте туда структуру ваших таблиц и некоторые примеры данных. Вам будет гораздо проще дать вам ответ с запросом – Kacper

+0

@Sal Я отредактировал ответ и добавил предложенный запрос. Пожалуйста, попробуйте – Kacper

+0

'with' clause определить данные, которые я использую позже в запросе. Вы можете думать об этом, как о представлении, определенном только для одного запроса. Подготавливает данные, содержащие только европейские города. 'c1' и' c2' - это просто псевдонимы для таблицы, определенной в разделе 'with'. @Sal – Kacper

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 [так] принимает только два значения, вы можете использовать это для предложения having:

 having min(city.iscapitol) <> max(city.iscapitol)