I'm having troubles using multiple OUTER JOINs, which I think I want to use to solve my problem.

My problem is to find all non-translated string values in our translations database, given the 4 following tables:

SOURCE (source_id PRIMARY KEY, language_id, value, ...)
TRANSLATION (translation_id PRIMARY KEY, language_id, value, ...)
TRANSLATION_PAIR (source_id, translation_id)
LANGUAGE(language_id PRIMARY KEY, name)

This seems to me the appropriate situation for using OUTER JOINs, but I cannot figure out how to get the null rows without the not-null rows.

Here's my best guess at this query:
SELECT s.source_id,tp.translation_pair_id,t.translation_id,t.language_id, l.name FROM source s
LEFT OUTER JOIN translation_pair tp USING(source_id)
LEFT OUTER JOIN translation t ON tp.translation_id = t.translation_id AND t.translation_id is null)
RIGHT OUTER JOIN language l on l.language_id = t.language_id;

To test this query, I have a string that only has a translation in English and used it in this test query. SELECT s.source_id,tp.translation_pair_id,t.translation_id,t.language_id, l.name
    FROM (select * FROM source s WHERE source_id = 159986) as s
        LEFT OUTER JOIN translation_pair tp USING(source_id)
LEFT OUTER JOIN translation t ON tp.translation_id = t.translation_id
        RIGHT OUTER JOIN language l on l.language_id = t.language_id;

This yields promising results:
source_id | translation_pair_id | translation_id | language_id | name -----------+---------------------+----------------+------------- +---------------------- | | | | Russian | | | | Danish
           |                     |                |             | Dutch
159986 | 1893187 | 1743833 | 4 | English | | | | Finnish | | | | French | | | | German | | | | Italian | | | | Japanese | | | | Korean | | | | Norwegian | | | | Simplified Chinese | | | | Spanish | | | | Swedish | | | | Traditional Chinese | | | | Portuguese | | | | Polish | | | | Turkish
           |                     |                |             | Czech
| | | | Brazilian Portuguese
(20 rows)

However, when I try to exclude the one not-null row, doing this:
SELECT s.source_id,tp.translation_pair_id,t.translation_id,t.language_id, l.name
    FROM (select * FROM source s WHERE source_id = 159986) AS s
        LEFT OUTER JOIN translation_pair tp USING(source_id)
LEFT OUTER JOIN translation t ON tp.translation_id = t.translation_id AND t.translation_id IS NULL
        RIGHT OUTER JOIN language l on l.language_id = t.language_id;

I expect 19 rows, but instead get 20 rows, all containing null values.
source_id | translation_pair_id | translation_id | language_id | name -----------+---------------------+----------------+------------- +---------------------- | | | | Russian | | | | Danish
           |                     |                |             | Dutch
| | | | English | | | | Finnish | | | | French | | | | German | | | | Italian | | | | Japanese | | | | Korean | | | | Norwegian | | | | Simplified Chinese | | | | Spanish | | | | Swedish | | | | Traditional Chinese | | | | Portuguese | | | | Polish | | | | Turkish
           |                     |                |             | Czech
| | | | Brazilian Portuguese
(20 rows)


I'm guessing I need to group the joins together, to avoid some associative problem.

Do you see what I'm doing wrong?

Thanks for the help,

Drew

---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?

              http://archives.postgresql.org

Reply via email to