【问题标题】:ORDER BY with CASE clause带有 CASE 子句的 ORDER BY
【发布时间】:2015-04-01 20:00:42
【问题描述】:

我想创建一个动态 order by 语句。

其目的是读取每日计划覆盖表(0 到 * 条记录)并决定在选定日期使用全局覆盖或存储覆盖。

我想过使用下面这样的 case 子句,但它没有按预期工作。

select * from schedule sdl 
where day = 3
and (sdl.store_id = 23331 or sdl.store_id is null)
order by
case when sdl.force is true 
then 'sdl.store_id nulls first' 
else 'sdl.store_id nulls last'
end 
limit 1

是否可以使用 case 语句创建 order-by 语句?或者也许有更好的方法来解决这个问题。

【问题讨论】:

标签: sql postgresql


【解决方案1】:

您似乎走在了正确的轨道上。您只需为每一行生成一个值,并使其对您希望它们的排序方式有意义。

select  *
from    schedule sdl
where   day = 3
    and (sdl.store_id = 23331 or sdl.store_id is null)
order by case when sdl.store_id is null and sdl.force then 0 --nulls in front
             when sdl.store_id is null and not sdl.force then 2 --nulls in back
             else 1 end; --everything else in the middle

在 PostgreSQL 9.4.1 上测试

【讨论】:

  • 只是为您的答案做出贡献。如果您想为中间结果获得不同的顺序而不是 else 1 -> else row_number() over (partition by primary_key_id order by primary_key_id desc) end
  • 这只会按照它们在结果集中出现的顺序“排序”行。仅将三个值 0 表示“空值优先”、1 表示“非空值”和 2 表示“空值最后”提供了更多的分组效果,允许按标准进行更多排序,从而在每个组内提供合理的排序。
  • 更不用说值 2 不能再用于“Nulls last”组了。您必须以某种方式跟踪生成的行号数,并将其设置为大于最后一行数的某个值。
  • 我的意思是我测试了它和它的工作原理。我想要实现的是,如果不存在空值,则按最后插入的 desc 对非空值进行排序并取第一个。与最后一个非空插入覆盖的优先级相同。
  • 你可以用order by case ... end, primary_key_id做同样的事情。这适用于空值之前和之后,仅在空值之前,仅在空值之后且根本没有空值。
【解决方案2】:

是的,有可能,您问题的评论中的链接显示了一个有效的示例,但看起来您的问题是 “第一个/最后一个空值”。这些不是有效的 postgres 构造。你的查询应该是这样的

select * from schedule sdl
where day = 3 and (sdl.store_id = 23331 or sdl.store_id is null)
order by
case when sdl.force is true
     then sdl.store_id end desc,   
case when sdl.force is false  
     then sdl.store_id end         
limit 1

asc 是默认排序(不需要明确指定)

【讨论】:

    【解决方案3】:

    尝试在 select 子句中使用大小写,然后按该字段排序。

    如果没有测试,我应该看起来像这样

    select *, 
    case when sdl.force is true 
      then 'sdl.store_id nulls first' 
      else 'sdl.store_id nulls last'
      end as orderfield 
    from schedule sdl 
    where day = 3
    and (sdl.store_id = 23331 or sdl.store_id is null)
    order by orderfield
    limit 1
    

    【讨论】:

    • 我不认为这是有效的。 'sdl.store_id nulls first'::text 因此它被解释为文本而不是实际的 store_id 引用
    • 哦,是的,我先忘记空值,最后忘记空值。对不起
    猜你喜欢
    • 1970-01-01
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    • 2021-07-20
    • 1970-01-01
    • 2022-01-13
    • 2021-01-21
    相关资源
    最近更新 更多