Mysql 查询从左到右优先使用 IN 子句查找

Mysql query to find first using IN clause with preference from left to right

我有一个测试 table 包含列(id、标题、语言)

id: primary_key (auto-increment)

unique_key(综合)关于语言和标题

id title language
1 Japanese JP
2 Australian AU
3 English EN
4 Hindi HI

我想要一个基于多语言标准的 return 1 或 0 行的查询。

查询应该 return 语言优先级从左到右的结果,如果从左到右没有找到第一种语言的行,则依次查找第二种语言。

Use-case:

languages result row_id remarks
JP,HI 1 As JP found at id=1
HI,JP 4 As HI found at id=4
RU,AU 2 As AU found at id=2, no row with language=RU
PK,ST no row As no language has value PK or ST

这是我尝试在语言列上使用 FIELD 子句的自定义顺序:

SELECT id, title, language
    FROM test WHERE language IN ('TH', 'AU','EN') ORDER BY 
FIELD(LANGUAGE,'TH','AU','EN') LIMIT 1;

Expected/Actual 输出:

id title language
2 Australian AU

我想知道有没有更好的方法(在性能可读性方面)来实现这个use-case?

将语言列表转换为行集:

SELECT test.id, test.title, language
FROM test 
JOIN (SELECT 'TH' language, 1 priority UNION ALL
      SELECT 'AU'         , 2          UNION ALL
      SELECT 'EN'         , 3          ) languages USING (language)
ORDER BY languages.priority LIMIT 1;

for 8+, the parameter format would be csv – Another coder

WITH RECURSIVE
parameter AS (
    SELECT @languages_as_CSV CSV
),
languages AS (
    SELECT SUBSTRING_INDEX(CSV, ',', 1) language, 
           SUBSTRING(CSV FROM 1 + LOCATE(',', CSV)) tail,
           1 priority
    FROM parameter
    UNION ALL
    SELECT SUBSTRING_INDEX(tail, ',', 1),
           SUBSTRING(tail FROM 1 + LOCATE(',', tail))
    FROM cte
    WHERE tail <> ''
)
SELECT test.id, test.title, language
FROM test 
JOIN languages USING (language)
ORDER BY languages.priority LIMIT 1;

即递归 CTE 解析 CSV 以分离值并添加优先级数据。然后执行相同的查询,并使用解析的行集代替静态语言列表。

@languages_as_CS 是为查询提供 CSV 语言列表的参数的占位符。

注意 - none 多余的字符。 'TH,AU,EN' 而不是 'TH, AU, EN'.

看看这是否有帮助:

SELECT ...
WHERE    FIND_IN_SET(language, languages)
ORDER BY FIND_IN_SET(language, languages)
如果没有匹配项,

FIND_IN_SET 将 return 为空集,因此需要一些额外的东西来处理“0”的情况。