子查询中的SQL聚合而不复制位置

时间:2016-07-16 17:51:23

标签: sql oracle subquery aggregate code-duplication

所以下面的查询工作正常,但没有找到一种方法来不重复子查询中的where子句和外部查询:

SELECT * FROM table WHERE --Cannot change this as it is hardcoded in ArcGIS layer definition, only can access WHERE

objectid IN (
    SELECT objectid
    FROM table a
    RIGHT JOIN (
        SELECT id, MIN(seq) as seq, --zone
        FROM table b 
        WHERE zone IN ( 'ZONE2', 'ZONE3', 'ZONE4') GROUP BY id) c
    ON a.id = c.id      
    AND a.seq = c.seq
    --AND a.zone = c.zone
    WHERE zone IN ( 'ZONE2', 'ZONE3', 'ZONE4') 
) 

我基本上想要做一些类似于注释掉的部分,这样可以删除外部重复的where子句......但是当然没有工作,因为没有分组。

  • 不能在区域使用MIN或MAX,因为根据相应的序号不能保证按字母顺序排列
  • 不能将GROUP BY区域改为MIN(seq)返回
  • 无法在外部查询中执行WHERE,因为子查询无法获得正确的MIN(seq)
  • 无法在内部查询中执行WHERE,因为其他区域中可能存在重复的序列号

我们在WHERE子句中有大约15种区域变体,它们会随着时间的推移而缓慢变化。因此,只是尽量减少重复,这可能有助于将其切换出来的长期可靠性。

非常感谢任何想法和帮助!

4 个答案:

答案 0 :(得分:1)

SELECT *
FROM   table
WHERE --Cannot change this as it is hardcoded in ArcGIS layer definition, only can access
objectid IN (
  SELECT objectid
  FROM   (
    SELECT objectid,
           seq,
           MIN( seq ) OVER ( PARTITION BY id /*, zone */ ) AS min_seq
    FROM   table
    WHERE  zone IN ( 'ZONE2', 'ZONE3', 'ZONE4')
  )
  WHERE seq = min_seq
)

答案 1 :(得分:0)

您可以使用相关子查询:

SELECT *
FROM table WHERE --Cannot change this as it is hardcoded in ArcGIS layer definition, only can access
WHERE objectid IN (SELECT a.objectid
                   FROM table a
                   WHERE a.seq = (SELECT min(seq) 
                                  FROM table b 
                                  WHERE b.zone = a.zone AND a.id = c.id
                                 ) AND
                        a.zone IN ( 'ZONE2', 'ZONE3', 'ZONE4') 
                  );

答案 2 :(得分:0)

根据Darrel的使用CTE的建议,我发现可以在外部查询中使用WITH子句。我一直认为它们只能在开始时使用。这是有效的代码:

SELECT * FROM table WHERE --Cannot change this as it is hardcoded in ArcGIS layer definition, only can access WHERE

objectid IN (
    with filtered_zones as (
        select objectid , id, zone, seq
        from table 
        where zone in ( 'ZONE2', 'ZONE3', 'ZONE4'))
    SELECT objectid
    FROM filtered_zones a
    JOIN (
        SELECT id, MIN(seq) as seq
        FROM filtered_zones b 
        GROUP BY id) c
    ON a.id = c.id      
    AND a.seq = c.seq)

答案 3 :(得分:-1)

你看过使用公用表表达式(CTE)

吗?

CTE有点像可重用的子查询。