--- /dev/null
+.. change::
+ :tags: bug, sql
+ :tickets: 4322
+
+ Added missing window function parameters
+ :paramref:`.WithinGroup.over.range_` and :paramref:`.WithinGroup.over.rows`
+ parameters to the :meth:`.WithinGroup.over` and
+ :meth:`.FunctionFilter.over` methods, to correspond to the range/rows
+ feature added to the "over" method of SQL functions as part of
+ :ticket:`3049` in version 1.1.
*util.to_list(order_by),
_literal_as_text=_literal_as_label_reference)
- def over(self, partition_by=None, order_by=None):
+ def over(self, partition_by=None, order_by=None, range_=None, rows=None):
"""Produce an OVER clause against this :class:`.WithinGroup`
construct.
:meth:`.FunctionElement.over`.
"""
- return Over(self, partition_by=partition_by, order_by=order_by)
+ return Over(
+ self, partition_by=partition_by, order_by=order_by,
+ range_=range_, rows=rows)
@util.memoized_property
def type(self):
return self
- def over(self, partition_by=None, order_by=None):
+ def over(self, partition_by=None, order_by=None, range_=None, rows=None):
"""Produce an OVER clause against this filtered function.
Used against aggregate or so-called "window" functions,
See :func:`~.expression.over` for a full description.
"""
- return Over(self, partition_by=partition_by, order_by=order_by)
+ return Over(
+ self, partition_by=partition_by, order_by=order_by,
+ range_=range_, rows=rows)
@util.memoized_property
def type(self):
func.row_number().over, range_=(-5, 8), rows=(-2, 5)
)
+ def test_over_within_group(self):
+ from sqlalchemy import within_group
+ stmt = select([
+ table1.c.myid,
+ within_group(
+ func.percentile_cont(0.5),
+ table1.c.name.desc()
+ ).over(
+ range_=(1, 2),
+ partition_by=table1.c.name,
+ order_by=table1.c.myid
+ )
+ ])
+ eq_ignore_whitespace(
+ str(stmt),
+ "SELECT mytable.myid, percentile_cont(:percentile_cont_1) "
+ "WITHIN GROUP (ORDER BY mytable.name DESC) "
+ "OVER (PARTITION BY mytable.name ORDER BY mytable.myid "
+ "RANGE BETWEEN :param_1 FOLLOWING AND :param_2 FOLLOWING) "
+ "AS anon_1 FROM mytable"
+ )
+
+ stmt = select([
+ table1.c.myid,
+ within_group(
+ func.percentile_cont(0.5),
+ table1.c.name.desc()
+ ).over(
+ rows=(1, 2),
+ partition_by=table1.c.name,
+ order_by=table1.c.myid
+ )
+ ])
+ eq_ignore_whitespace(
+ str(stmt),
+ "SELECT mytable.myid, percentile_cont(:percentile_cont_1) "
+ "WITHIN GROUP (ORDER BY mytable.name DESC) "
+ "OVER (PARTITION BY mytable.name ORDER BY mytable.myid "
+ "ROWS BETWEEN :param_1 FOLLOWING AND :param_2 FOLLOWING) "
+ "AS anon_1 FROM mytable"
+ )
+
+
+
def test_date_between(self):
import datetime
table = Table('dt', metadata,
"AS anon_1 FROM mytable"
)
+ def test_funcfilter_windowing_range(self):
+ self.assert_compile(
+ select([
+ func.rank().filter(
+ table1.c.name > 'foo'
+ ).over(
+ range_=(1, 5),
+ partition_by=['description']
+ )
+ ]),
+ "SELECT rank() FILTER (WHERE mytable.name > :name_1) "
+ "OVER (PARTITION BY mytable.description RANGE BETWEEN :param_1 "
+ "FOLLOWING AND :param_2 FOLLOWING) "
+ "AS anon_1 FROM mytable"
+ )
+
+ def test_funcfilter_windowing_rows(self):
+ self.assert_compile(
+ select([
+ func.rank().filter(
+ table1.c.name > 'foo'
+ ).over(
+ rows=(1, 5),
+ partition_by=['description']
+ )
+ ]),
+ "SELECT rank() FILTER (WHERE mytable.name > :name_1) "
+ "OVER (PARTITION BY mytable.description ROWS BETWEEN :param_1 "
+ "FOLLOWING AND :param_2 FOLLOWING) "
+ "AS anon_1 FROM mytable"
+ )
+
def test_funcfilter_within_group(self):
stmt = select([
table1.c.myid,