有postgres CLOSEST运算子吗?

问题描述

| 我正在寻找某种东西,给定一个像这样的表:
| id | number |
|  1 |     .7 |
|  2 |   1.25 |
|  3 |   1.01 |
|  4 |    3.0 |
查询
SELECT * FROM my_table WHERE
number
CLOSEST(1)
将返回第3行。我只关心数字。现在,我有一个过程可以遍历每一行并进行比较,但是我认为该信息应该可以从b树索引中获取,因此这可能是内置的,但我不能查找任何表明这样做的文档。     

解决方法

我可能对语法不太满意,但是此参数化查询(所有?取原始问题的\'1 \')应该运行很快,基本上是2个B-Tree查找[假定索引编号]。
SELECT * FROM
(
  (SELECT id,number FROM t WHERE number >= ? ORDER BY number LIMIT 1) AS above
  UNION ALL
  (SELECT id,number FROM t WHERE number < ? ORDER BY number DESC LIMIT 1) as below
) 
ORDER BY abs(?-number) LIMIT 1;
具有〜5e5行的表(索引在
number
上)的查询计划如下所示:
psql => explain select * from (
        (SELECT id,number FROM t WHERE number >= 1 order by number limit 1) 
        union all
        (select id,number from t where number < 1 order by number desc limit 1)
) as make_postgresql_happy 
order by abs (1 - number) 
limit 1;
                                                  QUERY PLAN
--------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.24..0.24 rows=1 width=12)
   ->  Sort  (cost=0.24..0.24 rows=2 width=12)
         Sort Key: (abs((1::double precision - public.t.number)))
         ->  Result  (cost=0.00..0.23 rows=2 width=12)
               ->  Append  (cost=0.00..0.22 rows=2 width=12)
                     ->  Limit  (cost=0.00..0.06 rows=1 width=12)
                           ->  Index Scan using idx_t on t  (cost=0.00..15046.74 rows=255683 width=12)
                                 Index Cond: (number >= 1::double precision)
                     ->  Limit  (cost=0.00..0.14 rows=1 width=12)
                           ->  Index Scan Backward using idx_t on t  (cost=0.00..9053.67 rows=66136 width=12)
                                 Index Cond: (number < 1::double precision)
(11 rows)
    ,您可以尝试这样的事情:
select *
from my_table
where abs(1 - number) = (select min(abs(1 - number)) from t)
与手动循环遍历表没有太大区别,但至少它可以让数据库在“数据库空间”内部进行循环,而不必在函数和数据库内部之间来回跳转。另外,将其全部推送到单个查询中可以使查询引擎知道您要执行的操作,然后可以尝试以一种明智的方式进行操作。     ,第二个答案是正确的,但是我在\“ UNION ALL \”上遇到错误:
DBD::Pg::st execute failed: ERROR:  syntax error at or near \"UNION\"
我用以下代码修复了它:
SELECT * FROM
  (
    (SELECT * FROM table WHERE num >= ? ORDER BY num LIMIT 1)
        UNION ALL
    (SELECT * FROM table WHERE num < ?  ORDER BY num DESC LIMIT 1)
  ) as foo
ORDER BY abs(?-num) LIMIT 1;
诀窍是从内部表中删除AS,并仅在UNION上使用它。     ,如果您希望在组内找到最接近的值,则此代码很有用。在这里,我根据列
val
接近目标值0.5的接近程度将表
tb
除以
column_you_wish_to_group_by
SELECT *
FROM (
  SELECT
    ROW_NUMBER() OVER (PARTITION BY t.column_you_wish_to_group_by ORDER BY abs(t.val - 0.5) ASC) AS r,t.*
  FROM
    tb t) x 
WHERE x.r = 1;
    

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...