简体   繁体   中英

Specifying window functions with joins in Postgres

I get a syntax error with this SQL command in Postgres, but it seems like it matches the command syntax specified in the SELECT documentation

select *, 
       row_number() over w 
from units 
   left outer join leases 
window w AS (partition by units.id order by leases.start desc)

As far as I can see this matches the syntax which says I can write any SQL statement that is in the form of:

SELECT * 
from (table joins) 
WINDOW window_name AS (window_definition)

and yet SQL tells me there's an error between leases and window . What's the error? Why am I misreading the documentation?

Here's the error:

2020-03-27 23:02:11.644 PDT [47717] ERROR:  syntax error at or near "WINDOW" at character 66
2020-03-27 23:02:11.644 PDT [47717] STATEMENT:  select *, row_number() over w from  units left outer join leases WINDOW w AS (partition by units.id order by leases.start desc)
ERROR:  syntax error at or near "WINDOW"
LINE 1: ...umber() over w from  units left outer join leases WINDOW w A...
                                                             ^

To clarify my question, I edited it to actually add a window function to the SELECT list, though it's not necessary per the Postgresql SQL spec. At any rate, adding the function doesn't take care of the syntax error; it remains at the same spot.

As hwnn has commented your sql is not in error because of your use of WINDOW, it's because you haven't put any predicates for the join

select *, 
   row_number() over w 
from 
  units u
  left outer join leases l on u.id = l.unitid
  --                       ^^^^^^^^^^^^^^^^^^
window w AS (partition by u.id order by l.start desc)

If you're aiming to improve your sql knowledge you might want to skip use of the WINDOW clause because (as far as I'm aware) it's not supported by all DBMS; learning syntax implemented by only some vendors when a more commonly implemented variant is available is unnecessarily limiting for you

select *, 
   row_number() over (partition by u.id order by l.start desc) 
from
  units u
  left outer join leases l on u.id = l.unitid

What are you trying to do? You are not using any window functions.

So the syntax is simply:

select *
from units u left outer join
     leases l 
     on <join conditions here>

The window clause would be used if you had a window function such as row_number() with an over clause.

You can add the window clause after the from clause:

select *,
       row_number() over w 
from units u left outer join
     leases l 
     on <join conditions here>
window w as (partition by u.id order by l.start desc);

It is not needed unless you are going to refer to it more than once, so this is typically used:

select *,
       row_number() over (partition by u.id order by l.start desc)
from units u left outer join
     leases l 
     on <join conditions here>;

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