In meiner Freizeit arbeite ich seit einigen Jahren an einer Android-Anwendung, einer Begleit-App für Magic: the Gathering. Ich habe versucht, eine Möglichkeit zu finden, alle verfügbaren Sprachen einzubeziehen, möchte meinen Benutzern jedoch nur eindeutige Elemente basierend auf ihren Spracheinstellungen anzeigen.

Beispielsweise gibt es 13 verschiedene Ausdrucke der Karte 'Torrential Gearhulk' in allen Sprachen und Erweiterungen. Ich möchte die 3 eindeutigen Ausdrucke anzeigen, die der bevorzugten Sprache des Benutzers entsprechen oder die jeweils verfügbare Sprache, wenn für einen bestimmten Satz für die bevorzugte Sprache des Benutzers kein Datensatz gefunden wird.

Ich habe unten einige Beispielergebnisse aufgeführt (irrelevante Spalten weggelassen).

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 |
+---------------------+------+------+------------------+

Beachten Sie, dass es nur zwei Datensätze mit einem set von 'pkld' und 'mps' gibt, deren Sprache 'en' ist.

Ich hätte gerne eine Abfrage, die Folgendes liefert, wenn ich nach Karten mit dem Namen 'Torrential Gearhulk' mit einer Sprachpräferenz von Japanisch (ja) suchen würde.

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

Ich möchte Folgendes zurückgeben, wenn die bevorzugte Sprache des Benutzers Englisch (en) ist oder wenn ein Datensatz für seine bevorzugte Sprache nicht gefunden werden konnte.

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

Ich habe bei einigen Google-Suchvorgängen verschiedene Methoden ausprobiert, aber keine hat mir die gewünschten Ergebnisse geliefert. Ich erinnere mich ehrlich gesagt nicht an all die verschiedenen Abfragen, die ich versucht habe, aber der neueste Vorschlag ist hier , was führte zu:

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 |
+---------------------+------+------+------------------+--------------------+
1
Andrew Speers 6 Okt. 2020 im 07:24

3 Antworten

Beste Antwort

Sie können dies mit der Fensterfunktion ROW_NUMBER() tun:

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

Siehe die Demo.
Ergebnisse:

> Name                | lang | set  | collector_number
> :------------------ | :--- | :--- | :---------------
> Torrential Gearhulk | ja   | kld  | 67              
> Torrential Gearhulk | en   | mps  | 2               
> Torrential Gearhulk | en   | pkld | 67s  
0
forpas 7 Okt. 2020 im 07:00

Verwenden Sie einfach verschachteltes select und geben Sie anstelle von 'ja' die gewünschte Sprache ein:

SELECT *
FROM (select * from cards where `lang` in ('ja', 'en') and `name` = 'Torrential Gearhulk')
GROUP BY `set`, `collector_number` 
0
Autocrab 6 Okt. 2020 im 04:49

Sie können dies verwenden:

SELECT * FROM cards WHERE Name='Torrential Gearhulk' ORDER BY CASE WHEN  lang = 'ja' THEN 2 ELSE 1 END desc
0
aryan agarwal 6 Okt. 2020 im 04:51