ORDER BY with CASE子句

时间:2015-04-01 20:00:43

标签: sql postgresql

我想按语句创建动态订单。

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

我想过使用像下面这样的案例,但它没有按预期工作。

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语句?或者也许在这个问题上有更好的方法。

3 个答案:

答案 0 :(得分: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上测试

答案 1 :(得分:0)

是的,有可能,您的问题的评论中的链接显示了一个有效的示例,但看起来您的问题是 " nulls first / last"。这些都不是有效的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是默认排序(不需要明确指定)

答案 2 :(得分:-2)

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

没有测试,我应该看起来像那样

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
相关问题