Skip to content

Commit efc7625

Browse files
authored
add argMax aggregation (#134)
1 parent ecb8516 commit efc7625

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
### 1.5.0
22
- feat: #140: Adding pre-commit with ruff as linter and code formatter.
33
- fix: #139: Fix to replicas query when using default as cluster name
4+
- feat: #134: add `argMax` aggregation https://clickhouse.com/docs/sql-reference/aggregate-functions/reference/argmax
45
- feat: #133: Fix simultaneous queries error when iteration is interrupted
56
- feat: #130: Add `distributed_migrations` database setting to support distributed migration queries.
67
- feat: #129: Add `toYearWeek` datetime functionality

clickhouse_backend/models/aggregates.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"uniqHLL12",
1212
"uniqTheta",
1313
"anyLast",
14+
"argMax",
1415
]
1516

1617

@@ -67,3 +68,10 @@ class uniqTheta(uniq):
6768

6869
class anyLast(Aggregate):
6970
pass
71+
72+
73+
class argMax(Aggregate):
74+
arity = 2
75+
76+
def _resolve_output_field(self):
77+
return self.get_source_fields()[0]

tests/aggregates/tests.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from django.db.models import Q
1+
from django.db.models import Q, F
22
from django.test import TestCase
33

44
from clickhouse_backend.models import (
@@ -11,6 +11,8 @@
1111
uniqTheta,
1212
)
1313

14+
from clickhouse_backend.models.aggregates import argMax
15+
1416
from .models import WatchSeries
1517

1618

@@ -170,6 +172,36 @@ def setUpTestData(cls):
170172
# Use bulk_create to insert the list of objects in a single query
171173
WatchSeries.objects.bulk_create(watch_series_list)
172174

175+
def test_argMax(self):
176+
result = (
177+
WatchSeries.objects.values("show")
178+
.annotate(episode=argMax("episode", "date_id"))
179+
.order_by("show")
180+
)
181+
182+
expected_result = [
183+
{"show": "Bridgerton", "episode": "S1E1"},
184+
{"show": "Game of Thrones", "episode": "S1E1"},
185+
]
186+
187+
self.assertQuerysetEqual(result, expected_result, transform=dict)
188+
189+
def test_argMax_output_field(self):
190+
result = (
191+
WatchSeries.objects.values("show")
192+
.annotate(date=argMax("date_id", "episode"))
193+
.annotate(week=F("date__week"), week_day=F("date__week_day"))
194+
.values("show", "week", "week_day")
195+
.order_by("show")
196+
)
197+
198+
expected_result = [
199+
{"show": "Bridgerton", "week": 20, "week_day": 6},
200+
{"show": "Game of Thrones", "week": 20, "week_day": 5},
201+
]
202+
203+
self.assertQuerysetEqual(result, expected_result, transform=dict)
204+
173205
def _test_uniq(self, cls_uniq):
174206
result = (
175207
WatchSeries.objects.values("show", "episode")

0 commit comments

Comments
 (0)