多个ID的公差带内的最近值

时间:2018-09-02 11:51:35

标签: sql postgresql

我正在寻找某种东西,给定这样一个表:

| channelid  | curveid  | xvalue   |
| 1          | 21       | 179.9216 |
| 1          | 21       | 180.4314 |
| 1          | 21       | 180.6528 |
| 1          | 21       | 180.9251 |
| 1          | 21       | 181.1334 |
| 1          | 21       | 181.4417 |
| 2          | 21       | 179.9513 |
| 2          | 21       | 180.1612 |
| 2          | 21       | 180.2022 |
| 2          | 21       | 180.8762 |
| 2          | 21       | 181.1331 |
| 2          | 21       | 181.2842 |
| 1          | 22       | 179.9213 |
| 1          | 22       | 180.4415 |
| 1          | 22       | 180.6226 |
| 1          | 22       | 180.9758 |
| 1          | 22       | 181.1639 |
| 1          | 22       | 181.4212 |
| 2          | 22       | 179.9715 |
| 2          | 22       | 180.1513 |
| 2          | 22       | 180.2326 |
| 2          | 22       | 180.8265 |
| 2          | 22       | 181.1437 |
| 2          | 22       | 181.2442 |

将最接近的x值返回给每个唯一的channelid curveid组合找到的值。

我找到了thisthis。这样,我可以找到总计最接近的值。但是我需要扩展它,以便它返回最接近每个唯一组合的位置。

SELECT * FROM table 
WHERE xvalue >= ($myvalue - .5) AND xvalue <= ($myvalue + .5) 
ORDER by abs(xvalue - $myvalue)

谢谢!

3 个答案:

答案 0 :(得分:1)

您可以使用

分组
select channelid, curveid,min(abs(xvalue - $myvalue)) 
from table
WHERE xvalue >= ($myvalue + .5) AND xvalue <= ($myvalue - .5) 
group by channelid, curveid 
ORDER by   min(abs(xvalue - $myvalue)) asc 

,如果您还需要相关的xvalue

select table.*, t.min_diff  from table  
inner join  (

  select channelid, curveid,min(abs(xvalue - $myvalue))  min_diff
  from table  
  WHERE xvalue >= ($myvalue + .5) AND xvalue <= ($myvalue - .5) 
  group by channelid, curveid 
  ORDER by   min(abs(xvalue - $myvalue)) asc 

) t on t.channelid = table.channelid 
      and y.curveid = table.curveid 
        and abs(table.xvalue - $myvalue) = t.min_diff 

答案 1 :(得分:1)

在Postgres中执行此操作的最佳方法是使用distinct on

SELECT DISTINCT ON (channelid, curveid) t.*
FROM table  
ORDER by channelid, curveid, abs(xvalue - $myvalue);

如果您知道所有想要的组合的最接近值在$myvalue的0.5以内,则可以添加where子句。

答案 2 :(得分:0)

我喜欢使用with首先准备数据。

with min as
   (
     select channelid, curveid, min(abs(xvalue-$myvalue)) mindifference 
     from table group by channelid, curveid
   )
select channelid, curveid, xvalue from min innner join table using (channelid, curveid) where abs(xvalue-$myvalue) = mindifference

这具有查看事前结果的优点,并且您可以轻松访问外部查询中的最小差异。