这可以通过使用子查询来完成
all_codes = Material.objects.values('Code')
Material.objects.annotate(
next=F('Code') + 1
).exclude(
next__in=all_codes
).aggregate(
minimum_code=Min('next')
)['minimum_code']
我们发现所有行,其中代码后的下一个数不在所有的代码值中,并且该注释的最小值是表中不存在的最低值。
希望这张表能说明发生了什么
|------|------|--------------------|
| Code | next | next in all Codes? |
|------|------|--------------------|
| 1 | 2 | True |
|------|------|--------------------|
| 2 | 3 | False | <- The minimum next not in all codes
|------|------|--------------------|
| 4 | 5 | True |
|------|------|--------------------|
| 5 | 6 | True |
|------|------|--------------------|
| 6 | 7 | False |
|------|------|--------------------|
记住,如果您使用的是MySQL
可怕的
在处理子查询时。在这种情况下,首先计算子查询,然后将结果作为列表传递(如果结果不太大)有时会更快
next__in=list(Material.objects.values_list('Code', flat=True))
这将只给出正确的结果,如果最小值不低于所有现有值,则应首先检查此情况。
minimum_code = Material.objects.aggregate(minimum_code=Min('Code'))['minimum_code']
if minimum_code > 1: # Or whatever default value you want
return 1
else:
# Do the above