Here is the situation.
Imagine a table with a few columns:
ID | Name | Language | … |
---|---|---|---|
1 | Bob | ES | … |
2 | Bob | EN | … |
3 | Bob | DE | … |
4 | Bill | EN | … |
5 | Jack | EN | … |
6 | Jack | DE | … |
7 | Jack | ES | … |
Given a specific language, I want to select all the IDs. If the language is not available, I want to default to EN.
So as an example, of I select for ES, I want to get:
ID | Name | Language | … |
---|---|---|---|
1 | Bob | ES | … |
4 | Bill | EN | … |
7 | Jack | ES | … |
And if I select for EN I want to get:
ID | Name | Language | … |
---|---|---|---|
2 | Bob | EN | … |
4 | Bill | EN | … |
5 | Jack | EN | … |
There can be up to 10 different languages, and in total there is close to 500k lines. There is about 90k different names.
For now I found one option using COALESCE, but this requires 2 queries for every line. Somelike:
SELECT COALESCE (
(SELECT ..... WHERE language = 'ES'),
(SELECT ..... WHERE language = 'EN')
)
But is there a more efficient way to do that? Something like:
SELECT ….. WHERE language = (‘ES’ AND IF NOT EXIST THEN ‘EN).
Thanks.
Edit:
The COALESCE approach doesn’t work. First, it can return only one column and second, it can return only one line.
3
Answers
You can use DISTINCT ON for this:
Edit: I missed the postgreSQL tag — the original answer was in MS SQL. I downloaded PostgreSQL and adapted it.
Typically I join to a users table and have simulated that in this response.
Get all users, connect them to the language table and then case statement the fall back if the desired language is missing. You could coalesce if you prefer.
With ES
WITH EN
== With just the table as I see it in your question ==
Here you grab everyone’s default, then go back and union everyone with EN default that doesn’t have the selected language.
Main Answer
For the sake of simulating / replicating the problem, I created the following temporary tables:
We perform the filter operation at least twice: once for the selected language and once of the default language. Therefore, I think it makes sense to create a function instead of repeating the query over and over:
COALESCE returns the first non NULL value. In the context of our problem, it return the first available id and language for a particular user.
Bonus
Let’s say that there are two default languages. Thus if the person does not speak the selected language or the first default language, show the second default language. Using the same approach:
By creating a function, we save ourself from repetitive writing and we make the query much more readable.