SQL:有没有比“COALESCE on two selects”更好的方法来查找 OR 子句中的第一个非空结果?

Posted

技术标签:

【中文标题】SQL:有没有比“COALESCE on two selects”更好的方法来查找 OR 子句中的第一个非空结果?【英文标题】:SQL: Is there a better way than "COALESCE on two selects" to find the first non-null result in an OR clause? 【发布时间】:2021-12-07 12:46:29 【问题描述】:

假设我有这张桌子:

ID LANG NAME DEFAULT
1 ENG Cinderella false
1 ENG The Ash Bride false
1 FRE Cendrillon true
1 GER Aschenputtel false

(“灰烬新娘”纯属捏造,同一个ID可以有多个同种语言的名字) SQL 查询应返回所需语言的名称,如果不存在,则返回默认语言。

因此,如果用户的设置是德语 (GER),则查找图书应返回标题“Aschenputtel”,但如果用户设置为西班牙语 (SPA),则应返回“Cendrillon”。

This question 提出了同样的问题,但答案建议通过名称列表进行双重连接,一个用于“lang='[preferred]'”,一个用于默认值,COALESCE 用于查找第一个非空结果。我担心如果名称列表很长(超过 50,000 个条目),当没有主键(因为每种语言可以有很多名称)时,这会导致性能问题,而且问题很老,所以想知道是否有一种更类似于

的方法
SELECT NAME WHERE ID=1 and (LANG='SPA' OR DEFAULT=true)

并返回 OR 子句的第一个非空结果。理想情况下,类似于:

(not functional)
SELECT COALESCE(SELECT NAME WHERE ID=1 and (LANG='SPA' OR DEFAULT=true));

会回来

CENDRILLON

(not functional)
SELECT COALESCE(SELECT NAME WHERE ID=1 and (LANG='ENG' OR DEFAULT=true));

会回来

CINDERELLA
THE ASH BRIDE

有任何一种平滑的方法可以让一个 SQL 查询产生预期的结果,而无需对长列表进行双重连接?还是双重选择的合并是唯一的答案?

【问题讨论】:

样本数据很好,但您还需要指定预期结果。 我想我做到了?但我已经编辑了这个问题以进一步澄清这一点。 【参考方案1】:

您可以通过某种方式对其进行排序,即 'SPA' 位于默认值(如果存在)之前,然后将结果限制为一条记录。

确切的语法取决于您使用的实际 DBMS。所以下面只是一个说明它的外观:

SELECT name
       FROM elbat
       WHERE lang = 'SPA'
              OR default
       ORDER BY CASE
                  WHEN lang = 'SPA' THEN
                    0
                  ELSE
                    1
                END
       LIMIT 1;

但我不知道这是否更有效。查看计划以获取相关信息。

【讨论】:

啊,太好了!当然!我从没想过在 ORDER BY 中使用 CASE。我目前正在使用 MariaDB,但我会尝试一下,看看它能带来什么。 嗯。当我在列表中有多个书名(不仅仅是 ID 1,还有更多,每个都有自己的标题列表)时,很难让这个工作。我想我必须以某种方式嵌套查询。 @Zimeon:根据您使用的 DBMS,您可以利用 row_number() 窗口函数。如果您需要这方面的帮助,您可以发布一个新问题。但请确保您标记了您这次使用的 DBMS。并提供minimal reproducible example,即涉及的表或其他对象的CREATE语句(粘贴文本,不要使用图像,不要链接到外部站点),INSERT示例数据 (dito) 的语句以及表格文本格式的示例数据的所需结果。

以上是关于SQL:有没有比“COALESCE on two selects”更好的方法来查找 OR 子句中的第一个非空结果?的主要内容,如果未能解决你的问题,请参考以下文章

有没有比在开头使用 1=1 更好的方法来动态构建 SQL WHERE 子句?

sql注入比我想象的更危险

比SQL还好用,又一门国产数据库语言诞生了

比SQL还好用,又一门国产数据库语言诞生了

为什么存储过程比sql语句效率高?

SQL 注入中的“参数化查询/准备语句”如何比转义用户输入更好