铁轨按时间顺序颠倒24小时

时间:2013-08-26 11:38:50

标签: sql ruby-on-rails ruby-on-rails-3 postgresql ruby-on-rails-4

我有一个模型,用于存储每个都有开始时间的事件。

开始时间由rails作为Time处理,但作为datetime存储在Postgres中(我假设)并且rails只是忽略日期并将其存储为2000-01-01 ......

我遇到的问题是订购它,以便午夜后开始的事件会在之后而不是之前显示。如何以不同的方式对它们进行排序并在24小时内分割事件,以便在下半场晚上事件之后出现第一个早上12小时的事件。 (如果是这样的话)

有什么想法吗?

c=Event.last
c.event_items.order(:time_start)

ORDER BY \“event_items \”。time_start ASC“

+-----+----------+-----------+-------------------------+---------+-------------------------+-------------------------+
| id  | event_id | artist_id | time_start              | area_id | created_at              | updated_at              |
+-----+----------+-----------+-------------------------+---------+-------------------------+-------------------------+
| 155 | 63       | 111       | 2000-01-01 00:40:00 UTC |         | 2013-08-24 21:21:57 UTC | 2013-08-26 00:07:44 UTC |
| 153 | 63       | 133       | 2000-01-01 01:10:00 UTC |         | 2013-08-24 21:21:57 UTC | 2013-08-26 00:07:44 UTC |
| 152 | 63       | 128       | 2000-01-01 02:00:00 UTC |         | 2013-08-24 21:21:57 UTC | 2013-08-26 00:07:44 UTC |
| 151 | 63       | 148       | 2000-01-01 22:10:00 UTC |         | 2013-08-24 21:21:57 UTC | 2013-08-26 00:07:44 UTC |
| 194 | 63       | 124       | 2000-01-01 23:00:00 UTC |         | 2013-08-26 00:07:44 UTC | 2013-08-26 00:07:44 UTC |
| 154 | 63       | 98        | 2000-01-01 23:50:00 UTC |         | 2013-08-24 21:21:57 UTC | 2013-08-26 00:07:44 UTC |
+-----+----------+-----------+-------------------------+---------+-------------------------+-------------------------+

我希望日期从12h(24h时钟)之后到12h之后...... +

例如在这个例子中我希望订单是22:10,23:00,23:50,00:40,01:10,02:00

2 个答案:

答案 0 :(得分:3)

postgres中有一个date_part函数,所以我认为你可以做这样的事情

Event.order("CAST(date_part('hour', time_start) AS Integer)/12 DESC,
             CAST(date_part('hour', time_start) AS Integer)%12 ASC")

如果您想以不同的模块划分时间,请尝试使用不同的分隔符。

<强>更新

我想我需要详细说明一下。

基本上我提取time_start 时间戳小时部分并将其转换(或cast)为整数因为我想使用整数而非时间。如果我们只是将小时除以12,它会给我们一个间隔,看看上面postgres doc的链接以获取更多细节。

所以第一个表达式CAST(date_part('hour', time_start) AS Integer)/12给我们 0 1 ; 0 如果小时 12 之前, 1 12 之后。这样做你想要的,在 12 之后的几个小时之后花费数小时 12 。它们将从23> 1开始分类。 12,然后11> 0虽然,所以不完全是你想要的。

因此第二个CAST(date_part('hour', time_start) AS Integer)%12。这将使用 23 =&gt; 11 22 =&gt; 10 ... 12 =&gt; 0 11 =&gt; 11 ... 0 =&gt; 0 等。所以我们可以按升序对它们进行排序。

顺便说一下,这不会对分钟进行排序,因此您可能希望将time_start ASC添加为第三个排序条件。我想您也可以将CAST(date_part('hour', time_start) AS Integer)添加到SELECT语句并为其命名,然后仅在ORDER BY上引用该名称。

希望这有帮助:)

答案 1 :(得分:1)

我想你可以这样做

c = Event.where(:time_start > 12.hours).order(:time_start) << Event.where(:time_start < 12.hours).order(:time_start)

这将一个接一个地连接两个结果,并给你想要的结果。