GIS SQL查询逻辑语法

时间:2016-06-03 16:36:20

标签: python sql gis

我有一个拥有数千个设施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的Facility ID。我只想在FacilityID的所有ZoneTypes上使用Max ZoneDistance。

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

我也试过了一个子查询,但是这个都没有用

我是SQL的半新手,我似乎无法弄清楚获得结果的逻辑。答案欢迎SQL或Python

2 个答案:

答案 0 :(得分:0)

在访问中使用此示例。我准备了关于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

答案 1 :(得分:0)

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