SQL 选择 "best" 行
SQL selection of "best" rows
我对 SQL 的了解很肤浅,我遇到了一个对我来说太复杂的查询。
我有 table 个带有名称和描述列的应用程序,它们是引用正确翻译的 ID。我有 table 个本地化字符串。
APPS(app_id、name_strid、description_strid)
字符串(str_id、lang_id、字符串)
我需要一个 return 所有应用的查询,每个字符串都有最佳翻译。
最好的语言顺序(让我说:it-it, it, en)
我找到了按语言排序所有应用程序的解决方案:
SELECT A.app_id, S1.string, S2.string
FROM APPS as A
JOIN STRINGS AS S1
ON A.name_strid = S1.str_id
JOIN STRINGS AS S2
ON A.description_strid = S2.str_id
WHERE S1.lang_id = S2.lang_id
AND S1.lang_id IN ("it-it", "it", "en")
ORDER BY
CASE S1.lang_id
WHEN "it-it" THEN 1
WHEN "it" THEN 2
WHEN "en" THEN 3
ELSE 4
END;
如何才能只获得最好的语言?
谢谢
在 SQL 的大多数方言中,您可以使用 row_number()
来解决此问题,但您没有该选项。解决这个问题的一种方法是使用相关子查询——这会为每个 str_id
提取第一个匹配的语言,然后您可以将其用于过滤。
SELECT A.app_id, S1.string, S2.string
FROM APPS as A JOIN
STRINGS AS S1
ON A.name_strid = S1.str_id JOIN
STRINGS AS S2
ON A.description_str_id = S2.str_id AND
S1.lang_id = S2.lang_id
WHERE S1.lang_id IN ('it-it', 'it', 'en') AND
S1.lang_id = (SELECT s3.LangId
FROM Strings s3
WHERE s3.str_id = S1.str_id
ORDER BY (CASE S3.lang_id
WHEN 'it-it' THEN 1
WHEN 'it' THEN 2
WHEN 'en' THEN 3
ELSE 4
END)
LIMIT 1
);
您可以使用 EXISTS
运算符来确保没有其他带有 "better score" 的翻译:
SELECT A.app_id, S1.string, S2.string
FROM APPS as A JOIN STRINGS AS S1 ON A.name_strid = S1.str_id
JOIN STRINGS AS S2 ON A.description_strid = S2.str_id
WHERE S1.lang_id = S2.lang_id
AND S1.lang_id IN ("it-it", "it", "en")
AND NOT EXISTS (SELECT 1
FROM STRINGS S3
WHERE (CASE S3.lang_id
WHEN "it-it" THEN 1
WHEN "it" THEN 2
WHEN "en" THEN 3
ELSE 4 END) < (CASE S1.lang_id
WHEN "it-it" THEN 1
WHEN "it" THEN 2
WHEN "en" THEN 3
ELSE 4 END)
我对 SQL 的了解很肤浅,我遇到了一个对我来说太复杂的查询。
我有 table 个带有名称和描述列的应用程序,它们是引用正确翻译的 ID。我有 table 个本地化字符串。
APPS(app_id、name_strid、description_strid) 字符串(str_id、lang_id、字符串)
我需要一个 return 所有应用的查询,每个字符串都有最佳翻译。 最好的语言顺序(让我说:it-it, it, en)
我找到了按语言排序所有应用程序的解决方案:
SELECT A.app_id, S1.string, S2.string
FROM APPS as A
JOIN STRINGS AS S1
ON A.name_strid = S1.str_id
JOIN STRINGS AS S2
ON A.description_strid = S2.str_id
WHERE S1.lang_id = S2.lang_id
AND S1.lang_id IN ("it-it", "it", "en")
ORDER BY
CASE S1.lang_id
WHEN "it-it" THEN 1
WHEN "it" THEN 2
WHEN "en" THEN 3
ELSE 4
END;
如何才能只获得最好的语言?
谢谢
在 SQL 的大多数方言中,您可以使用 row_number()
来解决此问题,但您没有该选项。解决这个问题的一种方法是使用相关子查询——这会为每个 str_id
提取第一个匹配的语言,然后您可以将其用于过滤。
SELECT A.app_id, S1.string, S2.string
FROM APPS as A JOIN
STRINGS AS S1
ON A.name_strid = S1.str_id JOIN
STRINGS AS S2
ON A.description_str_id = S2.str_id AND
S1.lang_id = S2.lang_id
WHERE S1.lang_id IN ('it-it', 'it', 'en') AND
S1.lang_id = (SELECT s3.LangId
FROM Strings s3
WHERE s3.str_id = S1.str_id
ORDER BY (CASE S3.lang_id
WHEN 'it-it' THEN 1
WHEN 'it' THEN 2
WHEN 'en' THEN 3
ELSE 4
END)
LIMIT 1
);
您可以使用 EXISTS
运算符来确保没有其他带有 "better score" 的翻译:
SELECT A.app_id, S1.string, S2.string
FROM APPS as A JOIN STRINGS AS S1 ON A.name_strid = S1.str_id
JOIN STRINGS AS S2 ON A.description_strid = S2.str_id
WHERE S1.lang_id = S2.lang_id
AND S1.lang_id IN ("it-it", "it", "en")
AND NOT EXISTS (SELECT 1
FROM STRINGS S3
WHERE (CASE S3.lang_id
WHEN "it-it" THEN 1
WHEN "it" THEN 2
WHEN "en" THEN 3
ELSE 4 END) < (CASE S1.lang_id
WHEN "it-it" THEN 1
WHEN "it" THEN 2
WHEN "en" THEN 3
ELSE 4 END)