简体   繁体   中英

SQL multiple alias in subquery

I have a setup where I would like to support a user defined subquery inside of a spatial query to identify overlapping polygons. Below is an example:

SELECT i1.id, i2.id
FROM
    (SELECT * FROM Images WHERE id > 600) i1,
    (SELECT * FROM Images WHERE id > 600) i2
WHERE ST_INTERSECTS(i1.footprint_latlon, i2.footprint_latlon) = TRUE
AND i1.id > i2.id

The above is working, but I more canonical way to do this exists.

The inner query is completely arbitrary here and the important component is that I am defining i1 and i2 using an identical query. I am doing this so that I have i1 and i2 aliases for the outer, spatial query.

Is it necessary to execute the inner query twice or does a better way to create the i1 , and i2 aliases exist? Lots of example on executing subqueries with a single (mandatory alias), but I am not seeing any examples of 'multi-aliases'.

I don't think there is a clean easy way to "alias an alias". You could do something like this:

WITH 
   i1 AS (SELECT * FROM Images WHERE id > 600),
   i2 AS (SELECT * FROM i1)
SELECT i1.id, i2.id
FROM
    i1, i2
WHERE ST_INTERSECTS(i1.footprint_latlon, i2.footprint_latlon) = TRUE
AND i1.id > i2.id

EDIT and much nicer, as suggested by @MatBailie :

WITH 
   i AS (SELECT * FROM Images WHERE id > 600)
SELECT i1.id, i2.id
FROM
    i AS i1, i AS i2
WHERE ST_INTERSECTS(i1.footprint_latlon, i2.footprint_latlon) = TRUE
AND i1.id > i2.id

My inclination would be one of the following:

select i1.id, i2.id
from images i1 join
     images i2
     on st_intersects(i1.footprint_latlon, i2.footprint_latlon)
where i1.id > 600 and i2.id > i1.id;

Or:

with ix as (
      select i.*
      from images i
      where i.id > 600
     )
select i1.id, i2.id
from ix AS i1 join
     ix AS i2
     on st_intersects(i1.footprint_latlon, i2.footprint_latlon)
where i2.id > i1.id;

I don't think there is a shortcut on performing the self join.

If you don't want to repeat the (complicated) subquery, you could either use a CTE (see Gordon Linoff's answer) or use a (temp) view containing the subquery [a CTE behaves differently for the optimiser/planner, for larger resultsets this could cause subobtimal performance] :


CREATE TEMP VIEW vv AS
     -- Put your complex subquery here ...
SELECT * FROM Images WHERE id > 600
        ;

SELECT i1.id, i2.id
FROM vv i1
JOIN vv i2 ON ST_INTERSECTS(i1.footprint_latlon, i2.footprint_latlon)
AND i1.id > i2.id
        ;
SELECT i1.id, i2.id
FROM Images i1,Images i2, 
WHERE i2.id > 600
  AND i1.id > i2.id
  AND ST_INTERSECTS(i1.footprint_latlon, i2.footprint_latlon) = TRUE

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM