【问题标题】:Is there a way to do this without CASE expression?有没有办法在没有 CASE 表达式的情况下做到这一点?
【发布时间】:2022-01-19 18:37:43
【问题描述】:

我想避免经常使用 CASE 表达式,尤其是对于像这里这样不那么复杂的逻辑。有没有更好的办法?

CASE
WHEN lower(player_status::text) in ( 'active'::text,'live'::text)
THEN true
ELSE false
END                  

如果没有 CASE,我可以得到相同的输出吗?

谢谢!

【问题讨论】:

    标签: postgresql boolean case


    【解决方案1】:

    实际上你不需要CASE 表达式。
    可以直接选择布尔表达式:

    SELECT COALESCE(lower(player_status::text), '') IN ('active'::text, 'live'::text) 
    FROM ...
    

    函数COALESCE()用于防止表达式在player_statusNULL的情况下返回NULL

    如果player_status 不可为空,则可以省略:

    SELECT lower(player_status::text) IN ('active'::text, 'live'::text) 
    FROM ...
    

    【讨论】:

    • 如果player_status 可以是NULL: select lower(NULL::text) in ( 'active'::text,'live'::text); NULL。所以你应该在里面扔一个COALESCE来防止这种情况发生。
    • @AdrianKlaver 正确,我会编辑。
    【解决方案2】:

    所以我收集到您正在寻找的最终结果是用户名和用户状态列表,但对于状态为“活动”或“活动”的用户,您希望显示布尔值 true 而不是实际存储在数据库,对吧?接受的答案有效,但我个人觉得使用select constants 更容易阅读:

    SELECT name, true as player_status
    FROM players.player_data
    WHERE player_status IN ('active', 'live')
    

    这将只显示活跃/活跃的玩家,他们的状态将显示为 true。如果您需要查询返回所有玩家,无论状态如何,同时仍为活动玩家进行文本替换,您可以简单地将上述查询与其逆查询结合在一起,尽管我不确定这是否比此线程中的其他两个建议的解决方案:

    SELECT name, true as player_status
    FROM players.player_data
    WHERE player_status IN ('active', 'live')
    
    UNION ALL
    
    SELECT name,false
    FROM players.player_data
    WHERE (player_status is null) 
       OR (player_status NOT IN ('active', 'live'))
    

    总而言之,就我个人而言,我可能会在 UI 层而不是在数据库查询中进行这种替换,这会使整个问题变得毫无意义,尽管这更多的是个人喜好问题。

    【讨论】:

    • ...但是对于状态为“活动”的用户,您希望显示文本“实时”而不是实际存储在数据库中的值您在哪里看到的? CASE 表达式返回 true 或 false 而不是字符串。
    • @forpas 感谢您的澄清,我错过了最初的查询。我已经更新了我的答案。
    猜你喜欢
    • 2019-01-18
    • 1970-01-01
    • 2021-07-09
    • 2023-03-15
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    • 2020-10-21
    • 2020-12-20
    相关资源
    最近更新 更多