Postgresql连接2个具有km范围的表

时间:2017-07-14 13:02:54

标签: sql postgresql join range

我需要帮助,在KM范围内使用两个表格连接不同距离的数字。范围是不同的,我需要功能1与feature2和3组合。

所以我需要一个范围连接,并且不知道如何解决这个问题。 特征2和3可能位于feature1的2个区域中,然后feature1应为'1'。但我没有一个好主意这样做。

因此,从0.1到0.1的NR 1在特征1中,其中f2 = A且f3 = X. 但是从4.2到6.0的NR 3在feature1 2和1中,因此feature1应该是1

NR  fromKM  toKM    feature1
1   0       1.4     1
1   1.4     3.8     2
1   3.8     7.2     1
1   7.2     36.7    2
2   0       14.6    1
3   0       5.2     2
3   5.2     10.6    1

NR  fromKM  toKM    featrure2   featrure3
1   0       0.1     A           X
1   0.1     0.3     B           Y
1   0.5     1.3     C           X
1   1.4     2.0     A           X
1   4.0     7.2     C           X
2   0.1     0.4     A           Y
2   0.4     1.6     C           X
3   0.1     4.2     B           X
3   4.2     6.0     B           Y
3   6.0     10.2    A           Y

所以输出应该是

NR  fromKM  toKM    feature1    featrure2   featrure3
1   0       0.1     1           A           X
1   0.1     0.3     1           B           Y
1   0.5     1.3     1           C           X
1   1.4     2.0     2           A           X
1   4.0     7.2     1           C           X
2   0.1     0.4     1           A           Y
2   0.4     1.6     1           C           X
3   0.1     4.2     2           B           X
3   4.2     6.0     1           B           Y
3   6.0     10.2    1           A           Y

1 个答案:

答案 0 :(得分:1)

您需要JOIN使用一个等式(对于NR)和两个不等式(对于fromKM和toKM)。你通常加入平等,但这实际上并不是必需的,你可以加入任何表达式返回一个布尔结果。

假设您的表名为t1t2,您可以使用:

SELECT
    t1.NR, t2.fromKM, t2.toKM, feature1, feature2, feature3
FROM
    t1 
    JOIN t2
        ON t2.NR = t1.NR AND t2.fromKM >= t1.fromKM AND t2.toKM <= t1.toKM
ORDER BY
    t1.NR, t2.fromKM

......你会得到:

nr | fromkm | tokm | feature1 | feature2 | feature3
-: | -----: | ---: | -------: | :------- | :-------
 1 |    0.0 |  0.1 |        1 | A        | X       
 1 |    0.1 |  0.3 |        1 | B        | Y       
 1 |    0.5 |  1.3 |        1 | C        | X       
 1 |    1.4 |  2.0 |        2 | A        | X       
 1 |    4.0 |  7.2 |        1 | C        | X       
 2 |    0.1 |  0.4 |        1 | A        | Y       
 2 |    0.4 |  1.6 |        1 | C        | X       
 3 |    0.1 |  4.2 |        2 | B        | X       
 3 |    6.0 | 10.2 |        1 | A        | Y       

你想要的输出是什么(除了一个C,我猜你的错误)。

您可以检查设置并在 dbfiddle here

进行测试

如果您希望获得最佳性能,可以使用一些特定的PostgreSQL功能,例如

  1. 使用numranges数据类型及其"overlaps" (&&)运算符或“包含范围”(@>)。
  2. 使用GIST index on the numranges
  3. 这意味着要做:

    CREATE INDEX idx_t1 ON t1 USING gist (NR, (numrange(fromKM, toKM, '[]'))) ;
    CREATE INDEX idx_t2 ON t2 USING gist (NR, (numrange(fromKM, toKM, '[]'))) ;
    

    通过以下方式查询:

    SELECT
        t1.NR, t2.fromKM, t2.toKM, feature1, feature2, feature3
    FROM
        t1 
        JOIN t2
            ON t2.NR = t1.NR AND numrange(t1.fromkm, t1.tokm, '[]') && numrange(t2.fromkm, t2.tokm, '[]')
    ORDER BY
        t1.NR, t2.fromKM ;
    

    当你有大表时,这是有道理的。您可以在 dbfiddle here

    中查看此第二个专门选项