SQLite GROUP BY 更喜欢某个值

SQLite GROUP BY preferring a certain value

几年来,我一直在利用业余时间开发 Android 应用程序,它是 Magic: the Gathering 的配套应用程序。我一直在尝试找出一种方法来包含所有可用的不同语言,但我只想根据用户的语言偏好向他们显示独特的项目。

例如,卡片 'Torrential Gearhulk' 在所有语言和扩展包中有 13 种不同的印刷形式。我想做的是显示用户首选语言的 3 种独特印刷品,或者如果找不到用户首选语言的特定集的记录,则显示任何可用语言。

我在下面包含了几个示例结果(省略了不相关的列)

SELECT *
FROM `cards`
WHERE `name` = 'Torrential Gearhulk'

+---------------------+------+------+------------------+
| Name                | lang | set  | collector_number |
+---------------------+------+------+------------------+
| Torrential Gearhulk | ru   | kld  |               67 |
| Torrential Gearhulk | ko   | kld  |               67 |
| Torrential Gearhulk | zht  | kld  |               67 |
| Torrential Gearhulk | pt   | kld  |               67 |
| Torrential Gearhulk | de   | kld  |               67 |
| Torrential Gearhulk | es   | kld  |               67 |
| Torrential Gearhulk | zhs  | kld  |               67 |
| Torrential Gearhulk | en   | mps  |                2 |
| Torrential Gearhulk | ja   | kld  |               67 |
| Torrential Gearhulk | fr   | kld  |               67 |
| Torrential Gearhulk | it   | kld  |               67 |
| Torrential Gearhulk | en   | kld  |               67 |
| Torrential Gearhulk | en   | pkld |              67s |
+---------------------+------+------+------------------+
SELECT *
FROM `cards`
WHERE `name` = 'Torrential Gearhulk'
GROUP BY `set`, `collector_number`

+---------------------+------+------+------------------+
| Name                | lang | set  | collector_number |
+---------------------+------+------+------------------+
| Torrential Gearhulk | ru   | kld  |               67 |
| Torrential Gearhulk | en   | mps  |                2 |
| Torrential Gearhulk | en   | pkld |              67s |
+---------------------+------+------+------------------+

请注意,只有 set 为 'pkld' 和 'mps' 的两个记录的语言为 'en'。

如果我要 运行 搜索语言偏好为日语 (ja) 的名为 'Torrential Gearhulk' 的卡片,我想要一个提供以下内容的查询。

+---------------------+------+------+------------------+
| Name                | lang | set  | collector_number |
+---------------------+------+------+------------------+
| Torrential Gearhulk | ja   | kld  |               67 |
| Torrential Gearhulk | en   | mps  |                2 |
| Torrential Gearhulk | en   | pkld |              67s |
+---------------------+------+------+------------------+

如果用户的首选语言是英语 (en) 或者如果找不到他们首选语言的记录,我想 return 以下内容。

+---------------------+------+------+------------------+
| Name                | lang | set  | collector_number |
+---------------------+------+------+------------------+
| Torrential Gearhulk | en   | kld  |               67 |
| Torrential Gearhulk | en   | mps  |                2 |
| Torrential Gearhulk | en   | pkld |              67s |
+---------------------+------+------+------------------+

我尝试了几种方法来进行一些 Google 搜索,但 none 给了我我正在寻找的结果。老实说,我不记得我尝试过的所有不同查询,但可以找到最近的建议 here,结果是:

SELECT *,
       MAX(`lang` = 'ja')
FROM `cards`
WHERE `name` = 'Torrential Gearhulk'
GROUP BY `set`, `collector_number`

+---------------------+------+------+------------------+--------------------+
| Name                | lang | set  | collector_number | MAX(`lang` = 'ja') |
+---------------------+------+------+------------------+--------------------+
| Torrential Gearhulk | ru   | kld  |               67 |                  1 |
| Torrential Gearhulk | en   | mps  |                2 |                  0 |
| Torrential Gearhulk | en   | pkld |              67s |                  0 |
+---------------------+------+------+------------------+--------------------+

只需使用嵌套 select 并输入您想要的任何语言而不是 'ja':

SELECT *
FROM (select * from cards where `lang` in ('ja', 'en') and `name` = 'Torrential Gearhulk')
GROUP BY `set`, `collector_number` 

你可以使用这个:

SELECT * FROM cards WHERE Name='Torrential Gearhulk' ORDER BY CASE WHEN  lang = 'ja' THEN 2 ELSE 1 END desc

您可以使用 ROW_NUMBER() window 函数来完成:

SELECT Name, lang, `set`, collector_number
FROM (
  SELECT *,
    ROW_NUMBER() OVER (PARTITION BY `set`, collector_number ORDER BY lang = 'ja' DESC) rn 
  FROM cards
  WHERE name = 'Torrential Gearhulk'
)
WHERE rn = 1

参见demo
结果:

> Name                | lang | set  | collector_number
> :------------------ | :--- | :--- | :---------------
> Torrential Gearhulk | ja   | kld  | 67              
> Torrential Gearhulk | en   | mps  | 2               
> Torrential Gearhulk | en   | pkld | 67s