如何用自定义查询替换未找到的行?

时间:2019-01-20 11:05:21

标签: sql postgresql

我有一个应用程序,其中每个新闻都有翻译成您的语言的版本。但是问题是可能没有翻译成用户语言,在这种情况下,我需要选择一种“标准(任何)”语言,但是我还不是很擅长。

数据:

create table languages(id int, name varchar(255), created_at timestamp);
create table posts(id int, created_at timestamp);
create table post_translations(
id int, post_id int,
language_id int, name varchar(255),
is_default boolean, is_approved boolean,
created_at timestamp);


insert into languages(id, name, created_at) values
('1', 'Russian', '2018-12-28 22:46:35'),
('2', 'English', '2018-12-28 22:46:35');

insert into posts(id, created_at) values
('1', '2018-12-28 22:46:35'),
('2', '2018-12-28 22:46:35');

insert into post_translations(id, post_id, language_id, name, is_default, is_approved) values
('1', '1', '1', 'Russian name - first post', true,true),
('1', '1', '1', 'Russian not moderated name - first post', false,false),
('1', '1', '2', 'English name - first post', false,true),
('1', '2', '2', 'English name - second post',true,true),
('1', '2', '2', 'Russian not moderated name - second post', false,false);

查询:

WITH r AS (
SELECT * FROM post_translations
  where is_approved = true and language_id = 1
  and post_id in (1,2)
)
SELECT * FROM r
UNION ALL
SELECT * FROM post_translations
  where is_approved = true
  and post_id in (1,2)
  AND NOT EXISTS (
SELECT * FROM post_translations 
   where is_approved = true and language_id = 1
   and post_id in (1,2)
);

DbFiddle.

在这里,我尝试用俄语翻译两个新闻,如果没有找到俄语,但没有出来,请进行标准(英语)翻译。

1 个答案:

答案 0 :(得分:1)

如果我理解正确,distinct on会做您想要的事情:

select distinct on (pt.post_id) pt.*
from post_translations pt
where pt.post_id in (1, 2)
order by pt.post_id,
         (case when language_id = 2 then 1
               when language_id = 1 then 2
               else 3
          end);

这将为每个post_id返回一行,以及case表达式优先的相应语言。