簡體   English   中英

使用條件在 Mysql 中查找不同的行

[英]Find distinct rows in Mysql by using conditions

標題模糊,抱歉。

我正在嘗試將客戶端代碼轉換為 Mysql 5.7 中的“純”sql(如果有任何區別 - 解決方案也只能適用於 MariaDB 10)。

我有一個“代碼”表和“code_translations”表。 我現在正在嘗試 output 代碼表中每個代碼的“最佳可用翻譯”。

如果有要求給我代碼“A”和翻譯語言“de”的翻譯 - 嘗試首先找到帶有“de”的翻譯。 如果未找到 - 使用“en”的可用翻譯(默認后備)。 如果沒有“en” - 采用當前排序確定的第一個可用翻譯。

從小提琴:

CREATE TABLE codes (id SERIAL, code TEXT, country TEXT);
CREATE TABLE code_translations (id SERIAL, code_id INT, language TEXT, label TEXT);

INSERT INTO codes (id, code, country) 
VALUES 
    (1, 'A', 'DE'),  
    (2, 'B', 'DE'),
    (3, 'C', 'DE');

INSERT INTO code_translations (code_id, language, label) 
VALUES
    (1, 'de', 'A-de'),
    (1, 'en', 'A-en'),
    (1, 'fr', 'A-fr'),
    (2, 'de', 'B-de'),
    (2, 'en', 'B-en'),
    (3, 'nl', 'C-nl'),
    (3, 'ru', 'C-ru');

基本 Select - 只產生所有行:

SELECT c.code,ct.label
FROM codes c
JOIN code_translations ct ON c.id=ct.code_id
-- WHERE ct.language=de
-- WHERE ct.language=fr
-- WHERE ct.language=ru

所需的 output:

-- WHERE language = de
-- output should be
-- |A|A-de| -- de is the direct match
-- |B|B-de| -- de is the direct match
-- |C|C-nl| -- first match determined by ordering

-- WHERE language = fr
-- output should be
-- |A|A-fr| -- fr is the direct match
-- |B|B-en| -- no "fr" - take "en"
-- |C|C-nl| -- first match determined by ordering

-- WHERE language = ru
-- output should be
-- |A|A-en| -- no "ru" - take "en"
-- |B|B-en| -- no "ru" - take "en"
-- |C|C-ru| -- ru is the direct match

您可以使用相關子查詢來獲取每個代碼的語言。 您可以先獲得所需的語言,然后是英語。 但是,如果這些不可用,則沒有“第一”語言——因為 SQL 表代表無序集。 您可以使用以下方法獲得任意語言:

select c.*, ct.language, ct.label
from (select c.*,
             (select ct.language
              from code_translations ct
              where ct.code_id = c.id
              order by ct.language = 'de' desc,
                       ct.language = 'en' desc
              limit 1
             ) as language
      from codes c
     ) c left join
     code_translations ct
     on ct.code_id = c.id and ct.language = c.language;

如果您有一個定義“第一”語言的順序,您可以將其作為第三個鍵包含在order by中。

是一個 db<>fiddle。

使用相關子查詢對每個codecode_translations行進行排序,使得第一行是查詢的語言(如果存在)、默認的后備語言(如果存在)或其他語言。
這種排序可以使用 function FIELD()來完成。
最后使用LIMIT 1只獲取第一行:

SELECT c.code,
       (
         SELECT ct.label
         FROM code_translations ct
         WHERE ct.code_id = c.id
         ORDER BY FIELD(ct.language, ?2, ?1) DESC
         LIMIT 1
       ) label
FROM codes c

?1替換為查詢的語言,將?2替換為備用語言。

請參閱演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM