Для моего домашнего задания я должен написать запросы из базы данных о мире. Я получил ошибку в одном из моих запросов и не могу понять, почему. Постановка проблемы для запроса, с которым у меня возникли проблемы:
Find all official languages, the country for which it is spoken, and the percentage of speakers
(percentage of speakers is calculated as percentage spoken times country population divided by 100).
Order results by the total number of speakers with the most popular language first. (238 results)
Ошибка, которую я получаю при попытке выполнить запрос с веб-сайта:
Query failed: ERROR: missing FROM-clause entry for table "city" LINE 1: ...kers FROM lab2.country AS
co JOIN lab2.country ON lab2.city.... ^
Код, который я написал для моего запроса:
case 11:
$q = "SELECT name, language, ((pecentage * population)/100) AS
percentage_of_speakers FROM lab2.country AS co JOIN lab2.country ON lab2.city.country_code WHERE
(is_official IS TRUE) ORDER BY percentage_of_speakers DESC";
$result = pg_query($q) or die ('Query failed: '. pg_last_error());
break;
Информация, которую я получаю для этого запроса, приходит из двух разных таблиц вместо одной. Я считаю, что мне нужно использовать оператор JOIN, чтобы получить данные из обеих таблиц. Вот 2 таблицы, которые используются. Спасибо за помощь заранее.
Table "lab2.country_language"Column | Type | Modifiers
--------------+-----------------------+----------------------------------------
country_code | character(3) | not null default ''::bpchar
language | character varying(30) | not null default ''::character varying
is_official | boolean | not null default false
percentage | real | not null default 0::real
Table "lab2.country"Column | Type | Modifiers
-----------------+-----------------------+--------------------------------------
country_code | character(3) | not null default ''::bpchar
name | character varying(52) | not null default ''::character varying
continent | continent | not null
region | character varying(26) | not null default ''::character varying
surface_area | real | not null default 0::real
indep_year | smallint |
population | integer | not null default 0
Я переформатировал ваш запрос, чтобы прочитать его, но я не решил проблемы. Вот как это выглядит с лучшим форматированием:
SELECT
name,
language,
((pecentage * population)/100) AS percentage_of_speakers
FROM lab2.country AS co
JOIN lab2.country ON lab2.city.country_code
WHERE is_official
ORDER BY percentage_of_speakers DESC
Проблема в запросе состоит из двух выделенных частей:
FROM lab2.country AS co
JOIN lab2.country ON lab2.city.country_code
^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
Первая проблема в том, что вы пытаетесь присоединиться lab2.country
к себе (lab2.country AS co JOIN lab2.country
). На самом деле вам разрешено делать это в SQL, и иногда это действительно полезно, но здесь это не то, что вам нужно. Вам нужно присоединиться lab2.country
в lab2.city
вместо.
Большая проблема заключается в ON
выражение в вашем соединении. Вы не можете просто присоединиться к такой ценности. предикат присоединения (это то, что часть после ON
ключевое слово) должно быть выражение что оценивает логическое значение (т. е. верно или ложно). Это то, что связывает две таблицы вместе.
Чтобы узнать, как решить эту проблему, я предлагаю вам изучить Учебник по соединениям PostgreSQL. Связанное руководство предоставляет пример того, как это работает, используя примеры таблиц из руководства PostgreSQL (это не таблицы в вашем вопросе):
SELECT *
FROM weather INNER JOIN cities ON (weather.city = cities.name);
Смотри как (weather.city = cities.name)
предоставляет своего рода «тестовое» выражение, которое можно запустить для каждой комбинации строк, чтобы увидеть, совпадают они или нет?
Надеюсь, это объяснит, как работают объединения, чтобы вы могли понять, как исправить исходный запрос.
(Кстати, я настоятельно рекомендую привыкнуть к тестированию кода в интерактивном режиме с помощью такого инструмента, как psql
или PgAdmin-III. Они намного удобнее, чем какой-либо случайный веб-инструмент запросов, и часто выдают более качественные сообщения об ошибках.)
Других решений пока нет …