代码之家  ›  专栏  ›  技术社区  ›  Happy Ahmad

django如何找到不在字段中的最小值?

  •  0
  • Happy Ahmad  · 技术社区  · 5 年前

    假设我们有1,2,4,5,6…的记录。。。在表Material中名为Code的字段中。如何写一个ORM返回3,这是不是在现有记录中的最小数量?

    0 回复  |  直到 5 年前
        1
  •  0
  •   Iain Shelvington    5 年前

    这可以通过使用子查询来完成

    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