为什么在sql语句中使用COALESCE()?

发布于 2024-09-25 12:35:52 字数 702 浏览 8 评论 0原文

我正在重构一些旧代码并偶然发现了这个命名查询 (它在mysql之上使用hibernate):

delete F from
    foo F
inner join user DU on F.user_id = DU.id
where
(COALESCE(:userAlternateId,null) is null or DU.alternate_id like :userAlternateId )
    and ( COALESCE(:fooId,null) is null or F.foo_id like :fooId )
    and (
        ( COALESCE(:fromUpdated,null) is null or F.updated_at>=:fromUpdated )
        and ( COALESCE(:toUpdated,null) is null or F.updated_at<=:toUpdated )
)

我不明白为什么这个COALESCE以这种方式使用: COALESCE(:userAlternateId,null) is null

这是性能黑客还是它使查询数据库独立还是......?

顺便说一句,userAlternateId 是一个字符串/varchar,其他 id 是长整型,from-to 是日期

I'm refactoring some old code and stumbled upon this named query
(It's using hibernate on top of mysql):

delete F from
    foo F
inner join user DU on F.user_id = DU.id
where
(COALESCE(:userAlternateId,null) is null or DU.alternate_id like :userAlternateId )
    and ( COALESCE(:fooId,null) is null or F.foo_id like :fooId )
    and (
        ( COALESCE(:fromUpdated,null) is null or F.updated_at>=:fromUpdated )
        and ( COALESCE(:toUpdated,null) is null or F.updated_at<=:toUpdated )
)

I don't understand why this COALESCE is being used in this fashion:
COALESCE(:userAlternateId,null) is null

Is this a performance hack or does it make the query database independent or ...?

btw userAlternateId is a string/varchar, other id's are longs and from-to are dates

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

樱桃奶球 2024-10-02 12:35:52

我想不出以这种方式使用 COALESCE 的任何理由。

以下语句是等效的

DELETE  F 
FROM    foo F
        INNER JOIN User DU on F.user_id = DU.id
WHERE   (:userAlternateId IS NULL OR DU.alternate_id LIKE :userAlternateId)
        AND (:fooId IS NULL OR F.foo_id LIKE :fooId)
        AND (:fromUpdated IS NULL OR F.updated_at >= :fromUpdated)
        AND (:toUpdated IS NULL OR F.updated_at <= :toUpdated)

I can't think of any reason for COALESCE being used this way.

Following statement is equivalent

DELETE  F 
FROM    foo F
        INNER JOIN User DU on F.user_id = DU.id
WHERE   (:userAlternateId IS NULL OR DU.alternate_id LIKE :userAlternateId)
        AND (:fooId IS NULL OR F.foo_id LIKE :fooId)
        AND (:fromUpdated IS NULL OR F.updated_at >= :fromUpdated)
        AND (:toUpdated IS NULL OR F.updated_at <= :toUpdated)
街角卖回忆 2024-10-02 12:35:52

是的,更多地考虑这一点,我赌我在这个问题的评论中建议的内容。它要么是自动生成的代码,并且是生成该代码的代码必须处理比此处处理的特定情况更普遍的问题的人为产物,要么是某人从诸如 COALESCE 之类的更合理的东西转向的人为产物(:userAlternateId, "not set") = "not set" to COALESCE(:userAlternateId,null) is null,虽然不太明智,但您可以看到某人如何可以从 A 到达 B。

Yep, thinking about this more, I'm betting on what I suggested in the comment on the question. Either it's auto-generated code, and its an artefact of the way the code generating that code has to handle more general issues than the particular case it's dealing with here, or it's an artefact of someone moving from something more reasonable like COALESCE(:userAlternateId, "not set") = "not set" to COALESCE(:userAlternateId,null) is null, which while not very sensible, is something that you can see how someone could get from A to B.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文