范围:按两个日期之间的差异排序
我想创建一个范围,从最近的日期到最远的日期对数据进行排序。
例如,我有3个值:
然后我想对最接近给定日期的日期进行排序: 2012-12-29
。
我应该得到这个顺序: 2, 3, 1
。
如果我选择2012-12-30
,结果必须是: 2012-12-30
。
我试过这样的事情:
scope :order_by_closest_date, lambda{|time| select("*, (date - DATE('#{time}')) AS time").order("time ASC") }
但它不起作用。
有关信息:Rails 3.2.9 Ruby 1.9.3 Postgresql 9.1.4。
有任何想法吗?
简单的查询
第一个示例根据初始问题使用date
列。
不确定Ruby语法,但正确的SQL语句将是:
SELECT * FROM tbl ORDER BY @(date_col - '2012-12-29'::date)
@
是“绝对价值”运营商。
切勿将date
或time
用作标识符。 虽然在PostgreSQL中允许(有一些限制),但这些是SQL标准中的保留字 ,它会导致令人困惑的错误消息和可能的意外错误。
出众的表演
其余部分根据注释中的更新使用timestamp
列。
对于小型表或临时查询,上述解决方案就可以了。 对于中型或大型桌子,如果性能很重要,我建议采用更复杂的方法。
Condicio sine qua non是date
或timestamp
列的索引 。 像这样:
CREATE INDEX tbl_my_timestamp_idx ON tbl(my_timestamp);
随着索引到位,将使用以下查询来查看更大表的简单性能:
SELECT * FROM ( ( SELECT * FROM tbl WHERE my_timestamp >= '2012-12-30 11:32'::timestamp ORDER BY my_timestamp LIMIT 3 ) UNION ALL ( SELECT * FROM tbl WHERE my_timestamp < '2012-12-30 11:32'::timestamp ORDER BY my_timestamp DESC LIMIT 3 ) ) x ORDER BY @extract('epoch' FROM (my_timestamp - '2012-12-28 11:32'::timestamp)) LIMIT 3;
-
UNION ALL
-SELECT
的两条腿周围的括号不是可选的。 需要将LIMIT
应用于每条腿。 -
如果按其他列排序,请在索引中反映 - 在这种情况下使用多列索引 。
怎么会这样?
第一个查询使用表达式作为条件。 Postgres必须计算每一行的值,然后按结果排序并选择前几行。 小桌子没问题,但是对于大桌子来说非常昂贵。 O(n) ; n
是表中的行数。 它不能使用普通索引。 加上一些非常重要的成本来排序和挑选所有行中的获胜者。
您可以在表达式上创建一个索引,这个索引最快,但只能用于比较的常量时间戳 - 几乎不是一个真实的用例。
第二个查询根据索引中的时间戳查找位置,按顺序读取下一对行的元组指针并直接从表中获取它们(甚至直接从索引中使用9.2中的仅索引扫描)。 两次,一次,一次下来,因为我们不知道同行如何比较。 但这只是2 x O(log(n)) ( 典型的b-tree查找成本 )计算仅针对少数预选行进行。 从小样本中挑选获胜者会带来微不足道的成本。
只需使用EXPLAIN ANALYZE
测试。 在对现实生活表的快速测试中,我获得了一个因子1000,其中包含一个50k行的表 。 并且它不断扩大规模。
尝试
scope :order_by_closest_date, lambda{|time| select("*, DATEDIFF(date,DATE('#{time}')) AS time").order("time ASC") }
- 搜索给定不同货币价格范围的模型
- rails – postgres错误:原因:库版本不兼容:libpq.5.dylib需要1.0.0或更高版本,
- 请求卡在PG :: Connection #async_exec中
- 有没有办法将Rails默认时间戳更改为Ymd H:i:s(而不是Ymd H:i:su)或laravel忽略Ymd H的小数部分:i:su?
- gem install pg error:无法理解Yosemite w / Ruby 2.1.5上的kern.osversion`14.0.0′
- 如何使用postgresqlvalidationRails中的重叠时间
- 安装gem’pg’时为什么会出错?
- 如何将PGSeaerch结果链接到嵌套资源中的索引页面?
- 更好的SQL – :group vs.:select =>’DISTINCT’