sql >> データベース >  >> RDS >> PostgreSQL

Django ORMのクエリによってグループ化された注釈付きフィールドの合計の最大値を計算しますか?

    集計の集計を行うことはできませんMax(Sum()) 、ORMを使用しているかどうかに関係なく、SQLでは無効です。代わりに、最大値を見つけるためにテーブルをそれ自体に結合する必要があります。これは、サブクエリを使用して実行できます。以下のコードは私には正しいように見えますが、これを実行するものがないため、完全ではない可能性があることに注意してください。

    from django.db.models import Subquery, OuterRef
    
    annotation = {
        'AcSum': Sum('intensity')
    }
    # The basic query is on Relation grouped by A and Category, annotated
    # with the Sum of intensity
    query = Relation.objects.values('a', 'b__category').annotate(**annotation)
    
    # The subquery is joined to the outerquery on the Category
    sub_filter = Q(b__category=OuterRef('b__category'))
    # The subquery is grouped by A and Category and annotated with the Sum
    # of intensity, which is then ordered descending so that when a LIMIT 1
    # is applied, you get the Max.
    subquery = Relation.objects.filter(sub_filter).values(
        'a', 'b__category').annotate(**annotation).order_by(
        '-AcSum').values('AcSum')[:1]
    
    query = query.annotate(max_intensity=Subquery(subquery))
    

    これにより、次のようなSQLが生成されます。

    SELECT a_id, category_id,
           (SELECT SUM(U0.intensity) AS AcSum
            FROM RELATION U0
            JOIN B U1 on U0.b_id = U1.id
            WHERE U1.category_id = B.category_id
            GROUP BY U0.a_id, U1.category_id
            ORDER BY SUM(U0.intensity) DESC
            LIMIT 1
           ) AS max_intensity
    FROM Relation
    JOIN B on Relation.b_id = B.id
    GROUP BY Relation.a_id, B.category_id
    

    Subqueryで結合を削除する方がパフォーマンスが高い場合があります array_aggなどのバックエンド固有の機能を使用する (Postgres)またはGroupConcat (MySQL)Relation.idsを収集します これらは外部クエリでグループ化されます。ただし、使用しているバックエンドはわかりません。



    1. Word、Excel、PowerPointでのキーボードのみのナビゲーションの使用(パート2:ダイアログボックス)

    2. GUIを使用してMySQLWorkbenchでユーザー権限を確認する方法

    3. AWSRDSデータベースインスタンスのセキュリティグループを変更します

    4. 組織にとってデータバックアップが重要である理由