在构建查询时需要一些帮助。我在@Rule MainActivityTestRule
表和bookings
表之间存在一对多的关系。每次预订状态更改时,都会生成一个新的booking_versions
行,其中指定了booking_versions
和status
列。我定位以获得状态状态更改之间的最短持续时间。这就是我现在尝试过的事情
created_at
它的rails代码仍然使用纯sql。此查询无法正常工作。也许你可以建议如何在最短时间内进行预订()。
巴士预订版本架构(item_id是预订的外键)
def self.min( filter )
query = <<-SQL
SELECT bv1.item_id AS 'obj_id', MIN(
bv2.created_at - bv1.created_at) AS 'mintime'
FROM bus_booking_versions AS bv1
INNER JOIN bus_booking_versions AS bv2
ON bv1.item_id = bv2.item_id
WHERE bv1.status = ?
AND bv1.created_at >= ?
AND bv1.created_at <= ?
AND bv2.status IN (?)
AND bv2.created_at >= ?
AND bv2.created_at <= ?
SQL
self.find_by_sql([query, filter.start_status, filter.from_start, filter.to_start, filter.end_statuses, filter.from_end, filter.to_end])
end
版本由纸尾宝石以这种方式创建
create_table "bus_booking_versions", force: :cascade do |t|
t.string "item_type", limit: 255, null: false
t.integer "item_id", limit: 4, null: false
t.string "event", limit: 255, null: false
t.string "whodunnit", limit: 255
t.text "object", limit: 4294967295
t.datetime "created_at"
t.integer "status", limit: 4
end
答案 0 :(得分:1)
由于我不知道您正在使用哪个数据库引擎,因此我会写出一般的SQL语句。您选择的数据库引擎可能有更好的方法。
您可以使用子查询来获取&#34; next&#34;而不是将同一个表连接在一起(您只需比较相同的行,由于您的bv1.item_id = bv2.item_id
)。在表中排。然后,您只需遍历表的一个实例。
具体来说,像这样的子查询,找到最晚的created_at,它比当前行的created_at(即&#34;下一行&#34;)更晚,是你想要的比较:
select min(created_at) from bus_booking_versions bv2 where bv1.item_id=bv2.item_id and created_at > bv1.created_at
这是一般查询。我已经使用了mysql的timediff函数,但您可以将其更改为您的特定数据库引擎计算日期时间差异的方法。根据您的数据库引擎,可能还有更好的方法来执行此操作。
select
bv1.item_id as 'obj_id',
mintime = timediff
(
(
select
min(created_at)
from
bus_booking_versions bv2
where
bv1.item_id=bv2.item_id
and created_at > bv1.created_at
),
bv1.created_at
)
from
#tmp1 bv1
where
timediff((select min(created_at) from bus_booking_versions bv2 where bv1.item_id=bv2.item_id and created_at > bv1.created_at), bv1.created_at) > 0
and timediff((select min(created_at) from bus_booking_versions bv2 where bv1.item_id=bv2.item_id and created_at > bv1.created_at), bv1.created_at) is not null
order by
timediff
希望它看起来很简单。我已经在选择中扩展了timediff /子查询,以便更清楚地了解正在发生的事情。 where子句中的timediff()与select中的完全相同,只是它们被压缩为一行。这是为了清除两个bus_booking_versions具有相同created_at的实例,或者比较时间戳是最终/唯一行(没有后续行)的实例。
您可以在where子句的其余部分添加以检查其他参数;我刚刚将它们排除在外以保持查询清晰易懂。如果您只想返回第一行,可以将.first
方法链接到ruby中的语句。