Craig's answer and your resulting query in the comments share the same flaw: The table anwendung
is at the right side of a LEFT JOIN
, which contradicts your obvious intent. You care about anwendung.name
and pick autor.entwickler
arbitrarily. I'll come back to that further down.
It should be:
SELECT DISTINCT ON (1) an.name, au.entwickler
FROM anwendung an
LEFT JOIN autor au ON an.name = au.anwendung;
DISTINCT ON (1)
is just a syntactical shorthand for DISTINCT ON (an.name)
. Positional references are allowed here.
If there are multiple developers (entwickler
) for an app (anwendung
) one developer is picked arbitrarily. You have to add an ORDER BY
clause if you want the "first" (alphabetically according to your locale):
SELECT DISTINCT ON (1) an.name, au.entwickler
FROM anwendung an
LEFT JOIN autor au ON an.name = au.anwendung
ORDER BY 1, 2;
As @mdahlman implied, a more canonical way would be:
SELECT an.name, min(au.entwickler) AS entwickler
FROM autor au
LEFT JOIN anwendung an ON an.name = au.anwendung
GROUP BY an.name;
Or, better yet, clean up your data model, implement the n:m relationship between anwendung
and autor
properly, add surrogate primary keys as anwendung
and autor
are hardly unique, enforce relational integrity with foreign key constraints and adapt your resulting query:
The proper way
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);
This query retrieves one row per app with one associated author (the 1st one alphabetically) or NULL if there are none:
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;
Result:
name | entwickler
-------+-----------------
bait |
bar | joe
foo | jane
shark | jane