我有三列 -
TheDate
- 显然是约会。TheID
- 一个严格增加的ID。TheType
- 记录类型。我想在几乎所有情况下都按TheID
排序,除了一种记录类型。特殊记录类型的记录必须出现在具有相同日期的所有记录的末尾。
示例:
我希望记录类型101
在所有其他具有相同日期的记录后显示。在所有其他情况下TheID
控制订单。
我的尝试如下:
ORDER BY
TheDate,
CASE WHEN TheType = 101 THEN 1 ELSE 0 END,
TheID
其中几乎做了我想做的事情,但做得更多 - 即它会按TheDate
重新排序,而不是我想要的。
如果数据后面出现相同的日期我并不在意 - 只是当包含类型101的记录序列(按TheID
排序)都具有相同的日期时我想要类型{{1最后一次。
答案 0 :(得分:1)
这很复杂。首先,您必须找到连续的日期记录,所以使用
thedate theid thetype 2014-07-12 5001 59 2014-07-12 5002 101 2014-07-12 5003 88 2014-07-13 5004 10 2014-07-12 5005 60
您会将2014-07-12标识为前三个记录的一次出现,另一次记录为最后一次记录。第二条记录必须在结果中排名第3,而不是#5。
通过使用第一个LAG
查看上一条记录来为连续记录提供组密钥,从而在组更改时创建一个标志,然后累积这些标记,从而实现此目的。
select thedate, theid, thetype
from
(
select
thedate, theid, thetype,
sum(new_group) over (order by theid) as group_key
from
(
select
thedate, theid, thetype,
case when lag(thedate) over (order by theid) = thedate then 0 else 1 as new_group
from mytable
) marked
) grouped
order by
group_key,
case when thetype = 101 then 1 else 0 end,
theid;
答案 1 :(得分:0)
在评论中授予的自由假设TheDate
不随递增TheId
而递减,如果r1.TheId < r2.TheId
则必须是r1.TheDate <= r2.TheDate
(&# 39; s非减少的定义)。在这种情况下,首先按TheDate
然后按TheId
排序会产生与单独排序TheId
相同的顺序。从另一个方向看,按TheId
排序会自动生成按TheDate
聚类的结果,并按日期排序。
但是你已经做的事情与按(TheDate
,TheId
)排序(我们已经建立的只与TheId
的排序相同)只是通过移动而不同特殊记录到每个日期集群的末尾,这正是你想要的。因此,您必须按照所需的顺序获得结果;如果你确实有任何问题,那么你必须对你这样做的方式不满意。例如,您可能关心查询性能。
但是,如果您现有的订购确实产生了正确的结果,那么我很难找到一种我希望能提供更好性能的替代方案。毫无疑问,排序可以通过不依赖于TheDate
不减少的方式产生,但我希望所有这些都是相对昂贵的计算。
答案 2 :(得分:0)
如果TheID不能为null,那么只需将TheID更改为null作为订单的一部分,其中TheType是一个特殊值:
order by TheDate,
case TheType
when 101 then null
else TheID
end nulls last