SQL 在不重复 Where 的情况下在子查询中聚合

SQL Aggregate In Subquery Without Duplicating Where

所以下面的查询工作得很好,但没有找到一种方法来不在子查询和外部查询中复制 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 子句...但这当然行不通,因为没有分组依据。

我们在 WHERE 子句中有大约 15 种不同的区域,它们会随着时间慢慢改变。所以只是尽量减少重复,这可能有助于将它们关闭的长期可靠性。

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

您可以使用相关子查询:

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') 
                  );

您是否看过使用常见的 table 表达式 (CTE)

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

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
)

根据 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)