MySQL:如何使用 COALESCE

Posted

技术标签:

【中文标题】MySQL:如何使用 COALESCE【英文标题】:MySQL: how to use COALESCE 【发布时间】:2011-08-02 07:09:42 【问题描述】:

假设我有下表:

TABLE: product
===============================================================================
| product_id | language_id | name           | description                     |
===============================================================================
| 1          | 1           | Widget 1       | Really nice widget. Buy it now! |
-------------------------------------------------------------------------------
| 1          | 2           | Lorem  1       |                                 |
-------------------------------------------------------------------------------

我如何查询它以使其尝试给我namedescription 其中language_id = 2,但如果列包含NULL,则回退到language_id = 1?

在上面的例子中,我应该得到Lorem 1 对应nameReally nice widget. Buy it now! 对应description

【问题讨论】:

【参考方案1】:
select name, description from product
where product_id = @pid
  and name is not null
  and description is not null
  and (language_id = @lang or language_id = 1)
order by language_id desc

其中@pid 是当前产品ID,@lang 是当前语言ID。

返回的第一行将包含当前名称和描述。

这假定行 language_id = 1 不会在名称或描述中包含 NULL

【讨论】:

这如何处理 NULL 列?这会退回到 language_id=1 的值吗? 抱歉,没有看到 NULL 要求。我将编辑选择 stmt。 NULL 是列的预期值。 我正在学习所有语言【参考方案2】:

假设:每个产品都有一个带有language = 1 的条目 下面的代码只是简单的 sql 来检索你想要的。

另一个主题是如果您想要您请求的行为.. 因为您可以在 namedescription 之间使用混合语言。我会以不同的方式设计它,如果两个字段之一为空,我将默认返回主要语言 (1)。

select p.product_id,
  coalesce(pl.name, p.name, 'No name') as name,
  coalesce(pl.description, p.description, 'No description') as description
from product p
  left join product pl on (pl.product_id = p.product_id and pl.language_id = :language_id)
where p.product_id = :product_id and p.language_id = 1

【讨论】:

【参考方案3】:

这里是一个使用 SQL 更新的例子:

它相当于 Oracle 的 NVL。 您可以使用参数在准备好的语句中使用它,如下所示

UPDATE
    tbl_cccustomerinfo
SET
    customerAddress = COALESCE(?,customerAddress),
    customerName =  COALESCE(?,customerName),
    description =  COALESCE(?,description)
WHERE
    contactNumber=?

【讨论】:

【参考方案4】:

这个怎么样?

SET @pid := 1, @lid := 2;
SELECT 
    COALESCE(name,(
        SELECT name
        FROM product
        WHERE product_id = @pid AND description IS NOT NULL
        LIMIT 1
    )) name, 
    COALESCE(description,(
        SELECT description
        FROM product
        WHERE product_id = @pid AND description IS NOT NULL
        LIMIT 1
    )) description
FROM product
WHERE product_id = @pid 
    AND (language_id = @lid 
    OR language_id = 1)
ORDER BY language_id DESC
LIMIT 1;

地点:

@pid:当前产品ID @lid: 当前语言 ID name 和/或description 的值可能为空 language_id = 2 项不存在

【讨论】:

【参考方案5】:
select p2.product_id
      ,coalesce(p2.name, p1.name, 'No name') as name
      ,coalesce(p2.description, p1.description, 'No description') as description
  from product p2
  left join product p1 on(
       p1.product_id = p2.product_id
   and p1.language_id = 1
  )
 where p2.product_id  = 1
   and p2.language_id = 2;

编辑1: 上面的查询假设 language=2 行存在,但 name/descr 可能为空。

编辑 2。 我只记得最近有人问过类似的问题。然后我发现是。您需要将产品与翻译分开。这就是使这个查询难以编写的原因。 Thomas answer 让你可以轻松地做你想做的事。

【讨论】:

伙计,这真是糟糕透了。睡吧罗尼斯! 如果 language=2 不存在怎么办?实际上,不能保证它会存在。 问题不同。上一个问题涉及建模。 Thomas 提供了关于如何建模和查询数据的建议。我决定使用不同于 Thomas 建议的建模方法。现在,我需要能够以与 Thomas 的建议类似的方式来查询它。

以上是关于MySQL:如何使用 COALESCE的主要内容,如果未能解决你的问题,请参考以下文章

Coalesce 函数如何处理数据类型

如何将 DSL.coalesce 与字段列表一起使用?

如何使用Oracle的COALESCE函数

如何在本机查询中使用 NVL 或 COALESCE 获取 Spring Data JPA 中的值列表

MySQL 在 WHERE 语句中使用 COALESCE 或 IFNULL 选择非 NULL 值

如何从 MySQL 中的 JSON 结果中删除括号