You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

window.py 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. from django.db.models.expressions import Func
  2. from django.db.models.fields import FloatField, IntegerField
  3. __all__ = [
  4. 'CumeDist', 'DenseRank', 'FirstValue', 'Lag', 'LastValue', 'Lead',
  5. 'NthValue', 'Ntile', 'PercentRank', 'Rank', 'RowNumber',
  6. ]
  7. class CumeDist(Func):
  8. function = 'CUME_DIST'
  9. output_field = FloatField()
  10. window_compatible = True
  11. class DenseRank(Func):
  12. function = 'DENSE_RANK'
  13. output_field = IntegerField()
  14. window_compatible = True
  15. class FirstValue(Func):
  16. arity = 1
  17. function = 'FIRST_VALUE'
  18. window_compatible = True
  19. class LagLeadFunction(Func):
  20. window_compatible = True
  21. def __init__(self, expression, offset=1, default=None, **extra):
  22. if expression is None:
  23. raise ValueError(
  24. '%s requires a non-null source expression.' %
  25. self.__class__.__name__
  26. )
  27. if offset is None or offset <= 0:
  28. raise ValueError(
  29. '%s requires a positive integer for the offset.' %
  30. self.__class__.__name__
  31. )
  32. args = (expression, offset)
  33. if default is not None:
  34. args += (default,)
  35. super().__init__(*args, **extra)
  36. def _resolve_output_field(self):
  37. sources = self.get_source_expressions()
  38. return sources[0].output_field
  39. class Lag(LagLeadFunction):
  40. function = 'LAG'
  41. class LastValue(Func):
  42. arity = 1
  43. function = 'LAST_VALUE'
  44. window_compatible = True
  45. class Lead(LagLeadFunction):
  46. function = 'LEAD'
  47. class NthValue(Func):
  48. function = 'NTH_VALUE'
  49. window_compatible = True
  50. def __init__(self, expression, nth=1, **extra):
  51. if expression is None:
  52. raise ValueError('%s requires a non-null source expression.' % self.__class__.__name__)
  53. if nth is None or nth <= 0:
  54. raise ValueError('%s requires a positive integer as for nth.' % self.__class__.__name__)
  55. super().__init__(expression, nth, **extra)
  56. def _resolve_output_field(self):
  57. sources = self.get_source_expressions()
  58. return sources[0].output_field
  59. class Ntile(Func):
  60. function = 'NTILE'
  61. output_field = IntegerField()
  62. window_compatible = True
  63. def __init__(self, num_buckets=1, **extra):
  64. if num_buckets <= 0:
  65. raise ValueError('num_buckets must be greater than 0.')
  66. super().__init__(num_buckets, **extra)
  67. class PercentRank(Func):
  68. function = 'PERCENT_RANK'
  69. output_field = FloatField()
  70. window_compatible = True
  71. class Rank(Func):
  72. function = 'RANK'
  73. output_field = IntegerField()
  74. window_compatible = True
  75. class RowNumber(Func):
  76. function = 'ROW_NUMBER'
  77. output_field = IntegerField()
  78. window_compatible = True