![](/img/trans.png)
[英]COALESCE(FIELD, “DEFAULT VALUE”) not working for postgresql + rails
[英]Rails with postgresql: extract field from time is not working
我按小時訂購收藏品時遇到問題。 但是首先是第一件事。
項目詳情:
Rails version 5.1.3
Ruby version 2.4.1-p111 (x86_64-linux)
Database adapter postgresql
這是我的收藏集的樣子:
#<DeliveryTimeslot:0x00562dd1ad2690
id: 1,
start: Sun, 02 Jan 2000 01:00:00 +03 +03:00,
stop: Sun, 02 Jan 2000 02:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:39 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:25 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1abcf98
id: 2,
start: Sun, 02 Jan 2000 02:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 03:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:39 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:25 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1ad23c0
id: 3,
start: Sat, 01 Jan 2000 03:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 04:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:39 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:26 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1ad1e70
id: 4,
start: Sat, 01 Jan 2000 04:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 05:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:26 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1ad1470
id: 5,
start: Sat, 01 Jan 2000 05:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 06:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:26 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1ad0bd8
id: 6,
start: Sat, 01 Jan 2000 06:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 07:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:26 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1acfdc8
id: 7,
start: Sat, 01 Jan 2000 07:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 08:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:26 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1acf7b0
id: 8,
start: Sat, 01 Jan 2000 08:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 09:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:26 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1acf198
id: 9,
start: Sat, 01 Jan 2000 09:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 10:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:26 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1acee00
id: 10,
start: Sat, 01 Jan 2000 10:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 11:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:26 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1aceb80
id: 11,
start: Sat, 01 Jan 2000 11:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 12:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:26 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1ace838
id: 12,
start: Sat, 01 Jan 2000 12:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 13:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:26 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1ace4c8
id: 13,
start: Sat, 01 Jan 2000 13:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 14:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:26 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1acdde8
id: 14,
start: Sat, 01 Jan 2000 14:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 15:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:26 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1acd758
id: 15,
start: Sat, 01 Jan 2000 15:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 16:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:26 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1acd168
id: 16,
start: Sat, 01 Jan 2000 16:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 17:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:26 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1acce20
id: 17,
start: Sat, 01 Jan 2000 17:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 18:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:27 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1acc678
id: 18,
start: Sat, 01 Jan 2000 18:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 19:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:27 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1abfb30
id: 19,
start: Sat, 01 Jan 2000 19:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 20:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:27 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1abf220
id: 20,
start: Sat, 01 Jan 2000 20:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 21:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:27 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1abea78
id: 21,
start: Sat, 01 Jan 2000 21:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 22:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:27 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1abe500
id: 22,
start: Sat, 01 Jan 2000 22:00:00 +03 +03:00,
stop: Sat, 01 Jan 2000 23:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:27 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1abdf10
id: 23,
start: Sat, 01 Jan 2000 23:00:00 +03 +03:00,
stop: Sun, 02 Jan 2000 00:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:27 +03 +03:00>,
#<DeliveryTimeslot:0x00562dd1abd3f8
id: 24,
start: Sun, 02 Jan 2000 00:00:00 +03 +03:00,
stop: Sun, 02 Jan 2000 01:00:00 +03 +03:00,
created_at: Wed, 05 Oct 2016 17:57:40 +03 +03:00,
updated_at: Thu, 16 Mar 2017 12:40:27 +03 +03:00>]
start
和stop
列在架構中均為t.time(因此記錄為ActiveSupport::TimeWithZone
)。
我要做的是按小時訂購它們,而我必須使用SQL語句來完成。
所以我嘗試了這個:
DeliveryTimeslot.all.order("EXTRACT (HOUR FROM start) DESC").map(&:id)
我希望得到這樣的數組:
[23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 24]
但是相反,我有這個:
[2, 1, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3]
我的想法是,這是因為三個記錄(ID為1、2和24)具有不同的開始日期(1月2日,而其他記錄具有1月1日)。 我上面寫的查詢不是應該從時間類型記錄中提取小時嗎? 真的是因為約會嗎? IDK為什么這不起作用,並且基本上我無法在DB中進行任何更改。 有什么提示我做錯了嗎? 有沒有在數據庫中沒有任何更改的提示?
只需使用DeliveryTimeslot.all.order("start DESC").map(&:id)
找到了解決方案。 它與我現有的應用程序一起工作
試試吧
DeliveryTimeslot.all.order('start DESC').sort_by {|item| item.start.to_date}.map{|item| item.id}
問題解決了。
我相信答案是這個問題是由db本身的構造引起的。 在postgresql doc :( https://www.postgresql.org/docs/9.2/static/datatype-datetime.html )中,他們說:
我們不建議將時間類型與時區一起使用
...並且ActiveRecord與ActiveSupport :: TimeWithZone混為一談。
一位同事告訴我按小時數對它進行排序。 在psql中看起來還可以:
kriseqsdb=# SELECT EXTRACT (HOUR FROM start) AS extracted_hour, * FROM delivery_timeslots ORDER BY EXTRACT (HOUR FROM start) DESC;
extracted_hour | id | start | stop | created_at | updated_at
----------------+----+----------+----------+----------------------------+----------------------------
23 | 2 | 23:00:00 | 00:00:00 | 2016-10-05 14:57:39.981764 | 2017-03-16 09:40:25.960571
22 | 1 | 22:00:00 | 23:00:00 | 2016-10-05 14:57:39.960375 | 2017-03-16 09:40:25.738402
21 | 24 | 21:00:00 | 22:00:00 | 2016-10-05 14:57:40.381005 | 2017-03-16 09:40:27.558225
20 | 23 | 20:00:00 | 21:00:00 | 2016-10-05 14:57:40.362648 | 2017-03-16 09:40:27.485668
19 | 22 | 19:00:00 | 20:00:00 | 2016-10-05 14:57:40.347286 | 2017-03-16 09:40:27.413084
18 | 21 | 18:00:00 | 19:00:00 | 2016-10-05 14:57:40.329297 | 2017-03-16 09:40:27.340032
17 | 20 | 17:00:00 | 18:00:00 | 2016-10-05 14:57:40.309307 | 2017-03-16 09:40:27.267091
16 | 19 | 16:00:00 | 17:00:00 | 2016-10-05 14:57:40.291424 | 2017-03-16 09:40:27.194525
15 | 18 | 15:00:00 | 16:00:00 | 2016-10-05 14:57:40.261229 | 2017-03-16 09:40:27.122137
14 | 17 | 14:00:00 | 15:00:00 | 2016-10-05 14:57:40.244531 | 2017-03-16 09:40:27.049617
13 | 16 | 13:00:00 | 14:00:00 | 2016-10-05 14:57:40.228901 | 2017-03-16 09:40:26.977144
12 | 15 | 12:00:00 | 13:00:00 | 2016-10-05 14:57:40.2118 | 2017-03-16 09:40:26.904671
11 | 14 | 11:00:00 | 12:00:00 | 2016-10-05 14:57:40.194678 | 2017-03-16 09:40:26.832177
10 | 13 | 10:00:00 | 11:00:00 | 2016-10-05 14:57:40.175353 | 2017-03-16 09:40:26.759804
9 | 12 | 09:00:00 | 10:00:00 | 2016-10-05 14:57:40.159382 | 2017-03-16 09:40:26.687357
8 | 11 | 08:00:00 | 09:00:00 | 2016-10-05 14:57:40.144921 | 2017-03-16 09:40:26.614746
7 | 10 | 07:00:00 | 08:00:00 | 2016-10-05 14:57:40.127898 | 2017-03-16 09:40:26.542091
6 | 9 | 06:00:00 | 07:00:00 | 2016-10-05 14:57:40.106023 | 2017-03-16 09:40:26.469586
5 | 8 | 05:00:00 | 06:00:00 | 2016-10-05 14:57:40.082284 | 2017-03-16 09:40:26.397126
4 | 7 | 04:00:00 | 05:00:00 | 2016-10-05 14:57:40.06161 | 2017-03-16 09:40:26.324512
3 | 6 | 03:00:00 | 04:00:00 | 2016-10-05 14:57:40.046009 | 2017-03-16 09:40:26.251731
2 | 5 | 02:00:00 | 03:00:00 | 2016-10-05 14:57:40.03066 | 2017-03-16 09:40:26.178915
1 | 4 | 01:00:00 | 02:00:00 | 2016-10-05 14:57:40.015266 | 2017-03-16 09:40:26.106172
0 | 3 | 00:00:00 | 01:00:00 | 2016-10-05 14:57:39.996529 | 2017-03-16 09:40:26.033393
(24 rows)
因此它通過Rails控制台執行:
DeliveryTimeslot.connection.select_all("SELECT EXTRACT (HOUR FROM start) AS extracted_hour, * FROM delivery_timeslots ORDER BY EXTRACT (HOUR FROM start) DESC")
=>
[23.0, 2, "23:00:00", "00:00:00", "2016-10-05 14:57:39.981764", "2017-03-16 09:40:25.960571"],
[22.0, 1, "22:00:00", "23:00:00", "2016-10-05 14:57:39.960375", "2017-03-16 09:40:25.738402"],
[21.0, 24, "21:00:00", "22:00:00", "2016-10-05 14:57:40.381005", "2017-03-16 09:40:27.558225"],
[20.0, 23, "20:00:00", "21:00:00", "2016-10-05 14:57:40.362648", "2017-03-16 09:40:27.485668"],
[19.0, 22, "19:00:00", "20:00:00", "2016-10-05 14:57:40.347286", "2017-03-16 09:40:27.413084"],
[18.0, 21, "18:00:00", "19:00:00", "2016-10-05 14:57:40.329297", "2017-03-16 09:40:27.340032"],
[17.0, 20, "17:00:00", "18:00:00", "2016-10-05 14:57:40.309307", "2017-03-16 09:40:27.267091"],
[16.0, 19, "16:00:00", "17:00:00", "2016-10-05 14:57:40.291424", "2017-03-16 09:40:27.194525"],
[15.0, 18, "15:00:00", "16:00:00", "2016-10-05 14:57:40.261229", "2017-03-16 09:40:27.122137"],
[14.0, 17, "14:00:00", "15:00:00", "2016-10-05 14:57:40.244531", "2017-03-16 09:40:27.049617"],
[13.0, 16, "13:00:00", "14:00:00", "2016-10-05 14:57:40.228901", "2017-03-16 09:40:26.977144"],
[12.0, 15, "12:00:00", "13:00:00", "2016-10-05 14:57:40.2118", "2017-03-16 09:40:26.904671"],
[11.0, 14, "11:00:00", "12:00:00", "2016-10-05 14:57:40.194678", "2017-03-16 09:40:26.832177"],
[10.0, 13, "10:00:00", "11:00:00", "2016-10-05 14:57:40.175353", "2017-03-16 09:40:26.759804"],
[9.0, 12, "09:00:00", "10:00:00", "2016-10-05 14:57:40.159382", "2017-03-16 09:40:26.687357"],
[8.0, 11, "08:00:00", "09:00:00", "2016-10-05 14:57:40.144921", "2017-03-16 09:40:26.614746"],
[7.0, 10, "07:00:00", "08:00:00", "2016-10-05 14:57:40.127898", "2017-03-16 09:40:26.542091"],
[6.0, 9, "06:00:00", "07:00:00", "2016-10-05 14:57:40.106023", "2017-03-16 09:40:26.469586"],
[5.0, 8, "05:00:00", "06:00:00", "2016-10-05 14:57:40.082284", "2017-03-16 09:40:26.397126"],
[4.0, 7, "04:00:00", "05:00:00", "2016-10-05 14:57:40.06161", "2017-03-16 09:40:26.324512"],
[3.0, 6, "03:00:00", "04:00:00", "2016-10-05 14:57:40.046009", "2017-03-16 09:40:26.251731"],
[2.0, 5, "02:00:00", "03:00:00", "2016-10-05 14:57:40.03066", "2017-03-16 09:40:26.178915"],
[1.0, 4, "01:00:00", "02:00:00", "2016-10-05 14:57:40.015266", "2017-03-16 09:40:26.106172"],
[0.0, 3, "00:00:00", "01:00:00", "2016-10-05 14:57:39.996529", "2017-03-16 09:40:26.033393"]
在那種情況下,對我來說還可以,因為這是我的主要擔憂。 但是要弄清楚我的問題並得到正確的數組,我只是將其映射為extracted_hour:
DeliveryTimeslot.connection.select_all("SELECT EXTRACT (HOUR FROM start) AS extracted_hour, * FROM delivery_timeslots ORDER BY EXTRACT (HOUR FROM start) DESC").rows.map { |row| row[0].to_i }
基本上得到了我所問的
=> [23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.