Ответ Крэйга и ваш результирующий запрос в комментариях имеют один и тот же недостаток: таблица anwendung
находится на правой стороне LEFT JOIN
, что противоречит вашим очевидным намерениям.Вы заботитесь о anwendung.name
и выбираете autor.entwickler
произвольно .Я вернусь к этому дальше.
Это должно быть:
SELECT DISTINCT ON (1) an.name, au.entwickler
FROM anwendung an
LEFT JOIN autor au ON an.name = au.anwendung;
DISTINCT ON (1)
- это всего лишь синтаксическая стенография для DISTINCT ON (an.name)
.Здесь допускаются позиционные ссылки.
Если для приложения (entwickler
) имеется несколько разработчиков (anwendung
), то один разработчик выбирается произвольно .Вы должны добавить предложение ORDER BY
, если хотите, чтобы "first" (в алфавитном порядке в соответствии с вашей локалью):
SELECT DISTINCT ON (1) an.name, au.entwickler
FROM anwendung an
LEFT JOIN autor au ON an.name = au.anwendung
ORDER BY 1, 2;
Как и подразумевал @mdahlman, более канонический способ будет:
SELECT an.name, min(au.entwickler) AS entwickler
FROM autor au
LEFT JOIN anwendung an ON an.name = au.anwendung
GROUP BY an.name;
Или, что еще лучше, очистите модель данных, правильно внедрите отношение n: m между anwendung
и autor
, добавьте суррогатные первичные ключи как anwendung
и autor
вряд ли уникальны, обеспечивают целостность отношений с ограничениями внешнего ключа и адаптируют ваш результирующий запрос:
Правильный путь
CREATE TABLE autor (
autor_id serial PRIMARY KEY -- surrogate primary key
, autor text NOT NULL);
INSERT INTO autor VALUES
(1, 'mike')
, (2, 'joe')
, (3, 'jane') -- worked on two apps
, (4, 'susi'); -- has no part in any apps (yet)
CREATE TABLE anwendung (
anwendung_id serial PRIMARY KEY -- surrogate primary key
, anwendung text UNIQUE); -- disallow duplicate names
INSERT INTO anwendung VALUES
(1, 'foo') -- has 3 authors linked to it
, (2, 'bar')
, (3, 'shark')
, (4, 'bait'); -- has no authors attached to it (yet).
CREATE TABLE autor_anwendung ( -- you might name this table "entwickler"
autor_id integer REFERENCES autor ON UPDATE CASCADE ON DELETE CASCADE
, anwendung_id integer REFERENCES anwendung ON UPDATE CASCADE ON DELETE CASCADE
, PRIMARY KEY (autor_id, anwendung_id)
);
INSERT INTO autor_anwendung VALUES
(1, 1)
,(2, 1)
,(3, 1)
,(2, 2)
,(3, 3);
Этот запрос извлекает одну строку на приложение с одним связанным автором (1-й в алфавитном порядке) или NULL, если их нет:
SELECT DISTINCT ON (1) an.anwendung, au.autor
FROM anwendung an
LEFT JOIN autor_anwendung au_au USING (anwendung_id)
LEFT JOIN autor au USING (autor_id)
ORDER BY 1, 2;
Результат:
name | entwickler
-------+-----------------
bait |
bar | joe
foo | jane
shark | jane