【问题标题】:GIS SQL Query Logic SyntaxGIS SQL 查询逻辑语法
【发布时间】:2016-06-03 16:36:20
【问题描述】:

我有一个包含数千个设施 ID 的 GIS 图层。

  • 对于每个设施 ID,可以有多个化学品 ID。
  • 对于每个化学品 ID,最多有 3 个区域类型。区域 A、B、C。但并不总是有 3 种区域类型,它会有所不同。
  • 每个设施 ID 的化学 ID 数量可以从 1 到多个不等。

我正在尝试做的是分解(或分组)此图层以显示哪个设施 ID 区域具有最大的缓冲距离,同时包括 ZoneType(重要)

这里是字段

             FacilityID, ChemicalID, ZoneType, ZoneDistance
ex rows:        1              2           A          1000
                1              2           B          900
                1              2           C          500
                1              5           A          1200
                1              5           B          900
                1              7           B          2000
                1              7           C          900
                2              13          A          200
                2              13          B          300
                2              13          C          600

预期结果:每个具有最大缓冲区和特定区域类型的 FacilityID 都有 1 行。所以对于 FacilityID 1- 我想要一行,它将是 ZoneType B,ZoneDistance 为 2000

FacilityID,ZoneType, ZoneDistance  
    1          B         2000
    2          C         600

我已经尝试了一些 SQL 语句,我得到了每个 ZoneType 的带有 Max ZoneDistance 的设施 ID。我只想要一个 FacilityID 中所有 ZoneTypes 的 Max ZoneDistance。

SELECT max(ZoneDistance), ZoneType, FacilityID
FROM AllZones group by ZoneType, FacilityID; 

我也尝试过子查询,但也没有用

我是半新的 SQL,我似乎无法弄清楚得到结果的逻辑。欢迎使用 SQL 或 Python 回答

【问题讨论】:

  • 您使用的是什么 gis 功能? Sql Server、Postgres、Oracle?
  • Max(ZoneDistance) 每个设施覆盖所有ZoneType 的平均缓冲区??
  • 我正在使用 Microsoft Access
  • 那么,只是sql查询,GIS在这里不相关吗?
  • 你真的应该考虑使用 Postgres 而不是 Access。我使用 ArcGis 和 Qgis 并且非常好。并且使这个查询会容易得多。只是一个MAX() over (PARTITION BY ZoneType, Facility)

标签: python sql gis


【解决方案1】:
Select f.FacilityID, 
     f.ZoneType,
     m.MaxZoneDistance
from AllZones f
     join (
          SELECT max(ZoneDistance) MaxZoneDistance,
               FacilityID 
          FROM AllZones 
          group by FacilityID
          ) m
          on f.facilityID=m.facilityID 
               and MaxZoneDistance=ZoneDistance

输出

FacilityID  ZoneType    MaxZoneDistance
1           B           2000
2           C           600

【讨论】:

    【解决方案2】:

    在访问中使用此示例。我准备了一个关于 MySQL 的演示。

    Achieving ROW_NUMBER / PARTITION BY in MS Access

    SQL Fiddle Demo

    SELECT *
    FROM (
            SELECT 
                t1.`ZoneType`,
                t1.`FacilityID`,
                t1.`ZoneDistance`,
                COUNT(*) AS `rn`
            FROM       Facility AS t1
            INNER JOIN Facility AS t2
                    ON t1.`FacilityID`   = t2.`FacilityID`
                   AND t1.`ZoneType`     = t2.`ZoneType`
                   AND t1.`ChemicalID`   = t2.`ChemicalID`
                   AND t1.`ZoneDistance` <= t2.`ZoneDistance`
            GROUP BY
                t1.`ZoneType`,
                t1.`FacilityID`,
                t1.`ZoneDistance`
            ORDER BY 
                t1.`ZoneType`,
                t1.`FacilityID`,
                t1.`ZoneDistance` DESC
           ) T
    WHERE rn = 1      
    ORDER BY `ZoneType`,`FacilityID`
    

    输出

    | ZoneType | FacilityID | ZoneDistance | rn |
    |----------|------------|--------------|----|
    |        A |          1 |         1200 |  1 |
    |        A |          2 |          200 |  1 |
    |        B |          1 |         2000 |  1 |
    |        B |          2 |          300 |  1 |
    |        C |          1 |          900 |  1 |
    |        C |          2 |          600 |  1 |
    

    我看到你的结果后找到了另一种方法

    Second DEMO

    SELECT *
    FROM (
            SELECT 
                t1.`FacilityID`,
                t1.`ChemicalID`, 
                t1.`ZoneType`, 
                t1.`ZoneDistance`,
                 ( SELECT COUNT(*)
                   FROM Facility as t2
                   WHERE t1.`FacilityID` = t2.`FacilityID`
                     AND ( ( t1.`ZoneDistance` < t2.`ZoneDistance`)
                        OR ( t1.`ZoneDistance` = t2.`ZoneDistance` and t1.`ZoneType` > t2.`ZoneType`)
                        OR ( t1.`ZoneDistance` = t2.`ZoneDistance` and t1.`ZoneType` = t2.`ZoneType` and t1.`ChemicalID` > t2.`ChemicalID`)
                         )
                 ) as rn
            FROM       Facility AS t1
            ORDER BY 
                t1.`FacilityID`,        
                t1.`ZoneDistance` DESC,
                t1.`ZoneType`, 
                t1.`ChemicalID`
        ) T
    WHERE rn = 0;
    

    输出

    FacilityID  ChemicalID  ZoneType    ZoneDistance    rn
    2           13          C           600             0
    1           7           B           2000            0
    

    【讨论】:

      猜你喜欢
      • 2011-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-09
      • 2018-10-30
      • 1970-01-01
      • 1970-01-01
      • 2011-06-12
      相关资源
      最近更新 更多