我有一个包含网页数据的表格,看起来像这样:
row_id ⁞ page_id ⁞ lang ⁞ title ⁞ slug
────────┼─────────┼──────┼────────────────────┼────────────────
1 ⁞1 ⁞ en ⁞ Welcome! ⁞ begin
2 ⁞1 ⁞ fr ⁞ Bienvenue! ⁞ bienvenue
3 ⁞2 ⁞ pl ⁞ Podstrona ⁞ podstrona
4 ⁞2 ⁞ en ⁞ Subpage ⁞ subpage
5 ⁞3 ⁞ pl ⁞ Podstrona 2 ⁞ podstrona-2
6 ⁞4 ⁞ fr ⁞ Coordonnées ⁞ coordonnees
7 ⁞5 ⁞ pl ⁞ Podstrona poziom 2 ⁞ podstrona-lvl-2
8 ⁞5 ⁞ en ⁞ Subpage Lvl 2 ⁞ subpage-lvl-2
9 ⁞6 ⁞ pl ⁞ Poziom 3 ⁞ poziom-3
10 ⁞6 ⁞ en ⁞ Level 3 ⁞ lvl-3
11 ⁞7 ⁞ pl ⁞ Błąd 404 ⁞ 404
12 ⁞7 ⁞ en ⁞ Error 404 ⁞ 404
13 ⁞7 ⁞ fr ⁞ Erreur 404 ⁞ 404
我想按优先顺序获取每个页面的单一语言版本。假设我想获取所有 fr 语言的页面,但是如果某些页面缺少该语言版本,则改为获取 en 版本,但是如果没有< em> en ,尝试 pl ,依此类推;因此在这种情况下,结果将如下所示:
row_id ⁞ page_id ⁞ lang ⁞ title ⁞ slug
────────┼─────────┼──────┼────────────────────┼────────────────
2 ⁞1 ⁞ fr ⁞ Bienvenue! ⁞ bienvenue
4 ⁞2 ⁞ en ⁞ Subpage ⁞ subpage
5 ⁞3 ⁞ pl ⁞ Podstrona 2 ⁞ podstrona-2
6 ⁞4 ⁞ fr ⁞ Coordonnées ⁞ coordonnees
8 ⁞5 ⁞ en ⁞ Subpage Lvl 2 ⁞ subpage-lvl-2
10 ⁞6 ⁞ en ⁞ Level 3 ⁞ lvl-3
13 ⁞7 ⁞ fr ⁞ Erreur 404 ⁞ 404
语言数量没有预先定义,但是每页必须至少具有一种语言版本。
可以处理大量查询,或者获取所有数据,然后通过PHP进行编程处理,但是我想知道是否有一种优雅的SQL(SQLite)解决方案可以在一个查询中解决这个问题? / p>
答案 0 :(得分:2)
有条件聚合:
select t.*
from (
select
page_id,
max(lang ='fr') fr,
max(lang ='en') en,
max(lang ='pl') pl
from tablename
group by page_id
) g inner join tablename t
on t.page_id = g.page_id
and t.lang = case 1
when g.fr then 'fr'
when g.en then 'en'
when g.pl then 'pl'
end
请参见demo。
或者,如果您的SQLite版本允许使用窗口函数:
with
cte(id, lang) as (
select * from
(values (1, 'fr'), (2, 'en'), (3, 'pl'))
),
langs as (
select t.*,
row_number() over (partition by t.page_id order by c.id) rn
from cte c inner join tablename t
on t.lang = c.lang
)
select row_id, page_id, lang, title, slug
from langs
where rn = 1
order by page_id
请参见demo。
结果:
| row_id | page_id | lang | title | slug |
| ------ | ------- | ---- | ------------- | ------------- |
| 2 | 1 | fr | Bienvenue! | bienvenue |
| 4 | 2 | en | Subpage | subpage |
| 5 | 3 | pl | Podstrona 2 | podstrona-2 |
| 6 | 4 | fr | Coordonnées | coordonnees |
| 8 | 5 | en | Subpage Lvl 2 | subpage-lvl-2 |
| 10 | 6 | en | Level 3 | lvl-3 |
| 13 | 7 | fr | Erreur 404 | 404 |
答案 1 :(得分:2)
这是一种优先级查询。我只会在case
中使用row_number()
表达式:
select t.*
from (select t.*,
row_number() over (case lang when 'fr' then 1 when 'en' then 2 when 'pl' then 3 else 4 end) as seqnum
from t
) t
where seqnum = 1;
在旧版本的SQLite中,您可以使用聚合和coalesce()
:
select page_id,
coalesce( max(case when lang = 'fr' then title end),
max(case when lang = 'en' then title end),
max(case when lang = 'po' then title end),
max(title) -- catchall for everything else
) as title,
coalesce( max(case when slug = 'fr' then title end),
max(case when slug = 'en' then title end),
max(case when slug = 'po' then title end),
max(slug) -- catchall for everything else
) as slug
from t
group by page_id;
或者,使用相关子查询:
select t.*
from t
where t.lang = (select t2.lang
from t t2
where t2.page_id = t.page_id
order by (case t2.lang when 'fr' then 1 when 'en' then 2 when 'po' then 3 else 4 end)
limit 1
) ;