{"title":"アグリゲーション (集計)","version":"5.0","locale":"ja","docname":"topics/db/aggregation","url":"/ja/5.0/topics/db/aggregation/","canonical":"https://djangodocs.dev/ja/5.0/topics/db/aggregation/","summary":"Djangoのデータベース抽象API のトピックガイドでは、個別のオブジェクトの作成、取得、削除を行うDjangoのクエリの使い方を説明しました。しかし、オブジェクトのコレクションを 集計 (アグリゲーション) した値や、集計することによって派生された値を取得しなければならないことがあります。…","html":"<h1>アグリゲーション (集計)<a class=\"heading-anchor\" href=\"#aggregation\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p><a class=\"reference internal\" href=\"/ja/5.0/topics/db/queries/\"><span class=\"doc\">Djangoのデータベース抽象API</span></a> のトピックガイドでは、個別のオブジェクトの作成、取得、削除を行うDjangoのクエリの使い方を説明しました。しかし、オブジェクトのコレクションを <em>集計 (アグリゲーション)</em> した値や、集計することによって派生された値を取得しなければならないことがあります。 このトピックガイドはで、Django のクエリを使って集計値を生成して返す方法を説明します。</p>\n<p>このガイドでは、以下のモデルを使用します。これらのモデルは、一連のオンライン書店の在庫を追跡するために使用されます。</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">models</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Author</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    <span class=\"n\">age</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">IntegerField</span><span class=\"p\">()</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Publisher</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">300</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Book</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">300</span><span class=\"p\">)</span>\n    <span class=\"n\">pages</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">IntegerField</span><span class=\"p\">()</span>\n    <span class=\"n\">price</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">DecimalField</span><span class=\"p\">(</span><span class=\"n\">max_digits</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">,</span> <span class=\"n\">decimal_places</span><span class=\"o\">=</span><span class=\"mi\">2</span><span class=\"p\">)</span>\n    <span class=\"n\">rating</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">FloatField</span><span class=\"p\">()</span>\n    <span class=\"n\">authors</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">ManyToManyField</span><span class=\"p\">(</span><span class=\"n\">Author</span><span class=\"p\">)</span>\n    <span class=\"n\">publisher</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">ForeignKey</span><span class=\"p\">(</span><span class=\"n\">Publisher</span><span class=\"p\">,</span> <span class=\"n\">on_delete</span><span class=\"o\">=</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CASCADE</span><span class=\"p\">)</span>\n    <span class=\"n\">pubdate</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">DateField</span><span class=\"p\">()</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Store</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">300</span><span class=\"p\">)</span>\n    <span class=\"n\">books</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">ManyToManyField</span><span class=\"p\">(</span><span class=\"n\">Book</span><span class=\"p\">)</span>\n</code></pre></div>\n<section id=\"cheat-sheet\">\n<h2>チートシート<a class=\"heading-anchor\" href=\"#cheat-sheet\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>お急ぎですか？ 上のモデルを使った場合の一般的な集計クエリは以下のようになります:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"go\"># Total number of books.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">count</span><span class=\"p\">()</span>\n<span class=\"go\">2452</span>\n\n<span class=\"go\"># Total number of books with publisher=BaloneyPress</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">publisher__name</span><span class=\"o\">=</span><span class=\"s2\">&quot;BaloneyPress&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">count</span><span class=\"p\">()</span>\n<span class=\"go\">73</span>\n\n<span class=\"go\"># Average price across all books, provide default to be returned instead</span>\n<span class=\"go\"># of None if no books exist.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Avg</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">aggregate</span><span class=\"p\">(</span><span class=\"n\">Avg</span><span class=\"p\">(</span><span class=\"s2\">&quot;price&quot;</span><span class=\"p\">,</span> <span class=\"n\">default</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">))</span>\n<span class=\"go\">{&#39;price__avg&#39;: 34.35}</span>\n\n<span class=\"go\"># Max price across all books, provide default to be returned instead of</span>\n<span class=\"go\"># None if no books exist.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Max</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">aggregate</span><span class=\"p\">(</span><span class=\"n\">Max</span><span class=\"p\">(</span><span class=\"s2\">&quot;price&quot;</span><span class=\"p\">,</span> <span class=\"n\">default</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">))</span>\n<span class=\"go\">{&#39;price__max&#39;: Decimal(&#39;81.20&#39;)}</span>\n\n<span class=\"go\"># Difference between the highest priced book and the average price of all books.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">FloatField</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">aggregate</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">price_diff</span><span class=\"o\">=</span><span class=\"n\">Max</span><span class=\"p\">(</span><span class=\"s2\">&quot;price&quot;</span><span class=\"p\">,</span> <span class=\"n\">output_field</span><span class=\"o\">=</span><span class=\"n\">FloatField</span><span class=\"p\">())</span> <span class=\"o\">-</span> <span class=\"n\">Avg</span><span class=\"p\">(</span><span class=\"s2\">&quot;price&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"go\">{&#39;price_diff&#39;: 46.85}</span>\n\n<span class=\"go\"># All the following queries involve traversing the Book&lt;-&gt;Publisher</span>\n<span class=\"go\"># foreign key relationship backwards.</span>\n\n<span class=\"go\"># Each publisher, each with a count of books as a &quot;num_books&quot; attribute.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Count</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">pubs</span> <span class=\"o\">=</span> <span class=\"n\">Publisher</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">num_books</span><span class=\"o\">=</span><span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;book&quot;</span><span class=\"p\">))</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">pubs</span>\n<span class=\"go\">&lt;QuerySet [&lt;Publisher: BaloneyPress&gt;, &lt;Publisher: SalamiPress&gt;, ...]&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">pubs</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">num_books</span>\n<span class=\"go\">73</span>\n\n<span class=\"go\"># Each publisher, with a separate count of books with a rating above and below 5</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Q</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">above_5</span> <span class=\"o\">=</span> <span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;book&quot;</span><span class=\"p\">,</span> <span class=\"nb\">filter</span><span class=\"o\">=</span><span class=\"n\">Q</span><span class=\"p\">(</span><span class=\"n\">book__rating__gt</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">))</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">below_5</span> <span class=\"o\">=</span> <span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;book&quot;</span><span class=\"p\">,</span> <span class=\"nb\">filter</span><span class=\"o\">=</span><span class=\"n\">Q</span><span class=\"p\">(</span><span class=\"n\">book__rating__lte</span><span class=\"o\">=</span><span class=\"mi\">5</span><span class=\"p\">))</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">pubs</span> <span class=\"o\">=</span> <span class=\"n\">Publisher</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">below_5</span><span class=\"o\">=</span><span class=\"n\">below_5</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">above_5</span><span class=\"o\">=</span><span class=\"n\">above_5</span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">pubs</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">above_5</span>\n<span class=\"go\">23</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">pubs</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">below_5</span>\n<span class=\"go\">12</span>\n\n<span class=\"go\"># The top 5 publishers, in order by number of books.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">pubs</span> <span class=\"o\">=</span> <span class=\"n\">Publisher</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">num_books</span><span class=\"o\">=</span><span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;book&quot;</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"s2\">&quot;-num_books&quot;</span><span class=\"p\">)[:</span><span class=\"mi\">5</span><span class=\"p\">]</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">pubs</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">num_books</span>\n<span class=\"go\">1323</span>\n</code></pre></div>\n</section>\n<section id=\"generating-aggregates-over-a-queryset\">\n<h2><code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> に対して集計を生成する<a class=\"heading-anchor\" href=\"#generating-aggregates-over-a-queryset\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django は集計を生成するために2つの方法を提供します。最初の方法は、 <code class=\"docutils literal notranslate\"><span class=\"pre\">クエリセット</span></code> 全体のサマリ値を生成する方法です。たとえば、販売されているすべての本の平均価格を計算したいとします。Django のクエリ構文は、全ての本のセットを記述する方法を提供します:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>必要なのは、この <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> に含まれるオブジェクトに対して合計値を計算する方法です。<code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> に <code class=\"docutils literal notranslate\"><span class=\"pre\">aggregate()</span></code> 句を加えることで計算されます:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Avg</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">aggregate</span><span class=\"p\">(</span><span class=\"n\">Avg</span><span class=\"p\">(</span><span class=\"s2\">&quot;price&quot;</span><span class=\"p\">))</span>\n<span class=\"go\">{&#39;price__avg&#39;: 34.35}</span>\n</code></pre></div>\n<p>この例では <code class=\"docutils literal notranslate\"><span class=\"pre\">all()</span></code> は冗長なので、次のように単純化できます:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">aggregate</span><span class=\"p\">(</span><span class=\"n\">Avg</span><span class=\"p\">(</span><span class=\"s2\">&quot;price&quot;</span><span class=\"p\">))</span>\n<span class=\"go\">{&#39;price__avg&#39;: 34.35}</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">aggregate()</span></code> 句への引数は計算したい集約値を表します - この例では、 <code class=\"docutils literal notranslate\"><span class=\"pre\">Book</span></code> モデルの <code class=\"docutils literal notranslate\"><span class=\"pre\">price</span></code> フィールドの平均になります。 利用可能な集約関数の一覧は <a class=\"reference internal\" href=\"/ja/5.0/ref/models/querysets/#aggregation-functions\"><span class=\"std std-ref\">QuerySet リファレンス</span></a> にあります。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">aggregate()</span></code> は <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> の終了句で、呼び出されると名前と値のペアの辞書を返します。名前は集計句の識別子で、値は計算された集計句です。名前はフィールド名と集計関数から自動的に生成されます。もし集計値の名前を手動で指定したい場合は、集計句を指定する際にその名前を指定することで指定できます:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">aggregate</span><span class=\"p\">(</span><span class=\"n\">average_price</span><span class=\"o\">=</span><span class=\"n\">Avg</span><span class=\"p\">(</span><span class=\"s2\">&quot;price&quot;</span><span class=\"p\">))</span>\n<span class=\"go\">{&#39;average_price&#39;: 34.35}</span>\n</code></pre></div>\n<p>複数の集計を行いたい場合は、 <code class=\"docutils literal notranslate\"><span class=\"pre\">aggregate()</span></code> 句に別の引数を追加します。もし、すべての書籍の最高価格と最低価格を知りたい場合は、このクエリを発行します:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Avg</span><span class=\"p\">,</span> <span class=\"n\">Max</span><span class=\"p\">,</span> <span class=\"n\">Min</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">aggregate</span><span class=\"p\">(</span><span class=\"n\">Avg</span><span class=\"p\">(</span><span class=\"s2\">&quot;price&quot;</span><span class=\"p\">),</span> <span class=\"n\">Max</span><span class=\"p\">(</span><span class=\"s2\">&quot;price&quot;</span><span class=\"p\">),</span> <span class=\"n\">Min</span><span class=\"p\">(</span><span class=\"s2\">&quot;price&quot;</span><span class=\"p\">))</span>\n<span class=\"go\">{&#39;price__avg&#39;: 34.35, &#39;price__max&#39;: Decimal(&#39;81.20&#39;), &#39;price__min&#39;: Decimal(&#39;12.99&#39;)}</span>\n</code></pre></div>\n</section>\n<section id=\"generating-aggregates-for-each-item-in-a-queryset\">\n<h2><code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> の各アイテムに対する集計を生成する<a class=\"heading-anchor\" href=\"#generating-aggregates-for-each-item-in-a-queryset\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p><a class=\"reference internal\" href=\"/ja/5.0/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code></a> 内の各オブジェクトに対して個別の集計を生成することもできます。たとえば、書籍の一覧を取得しようとする場合には、それぞれの書籍に寄稿している著者が何名いるのかを知りたいこともあるでしょう。 各 Book は Author に対して多対多のリレーションを持っています; この <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> 内で、各書籍の関係性を集計できます。</p>\n<p>オブジェクトごとの集計は <a class=\"reference internal\" href=\"/ja/5.0/ref/models/querysets/#django.db.models.query.QuerySet.annotate\" title=\"django.db.models.query.QuerySet.annotate\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">annotate()</span></code></a> 句を使うことで生成することができ ます。 <code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> が指定されると、 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> の各オブジェクトは 指定された値で注釈付け (annotate) されます。</p>\n<p>これらのアノテーションの構文は <a class=\"reference internal\" href=\"/ja/5.0/ref/models/querysets/#django.db.models.query.QuerySet.aggregate\" title=\"django.db.models.query.QuerySet.aggregate\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">aggregate()</span></code></a> 句の構文と同じです。 <code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> の各引数は計算される集計を記述します。たとえば、書籍に著者の数をアノテートする場合です:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"go\"># Build an annotated queryset</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Count</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">q</span> <span class=\"o\">=</span> <span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;authors&quot;</span><span class=\"p\">))</span>\n<span class=\"go\"># Interrogate the first object in the queryset</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">q</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n<span class=\"go\">&lt;Book: The Definitive Guide to Django&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">q</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">authors__count</span>\n<span class=\"go\">2</span>\n<span class=\"go\"># Interrogate the second object in the queryset</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">q</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n<span class=\"go\">&lt;Book: Practical Django Projects&gt;</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">q</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">authors__count</span>\n<span class=\"go\">1</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">aggregate()</span></code> と同様に、アノテーションの名前は集計関数の名前と集計されるフィールドの名前から自動的に生成されます。アノテーションを指定するときにエイリアスを指定することで、このデフォルト名を上書きできます。</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">q</span> <span class=\"o\">=</span> <span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">num_authors</span><span class=\"o\">=</span><span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;authors&quot;</span><span class=\"p\">))</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">q</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">num_authors</span>\n<span class=\"go\">2</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">q</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">num_authors</span>\n<span class=\"go\">1</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">aggregate()</span></code> とは違って、<code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> は最終句では ありません 。<code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> 句のアウトプットは <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> です; この <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> は、他の <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> の操作によって修正可能です。 <code class=\"docutils literal notranslate\"><span class=\"pre\">filter()</span></code>、<code class=\"docutils literal notranslate\"><span class=\"pre\">order_by</span></code> などに加えて、別の <code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> を追加呼び出しすることもできます。</p>\n<section id=\"combining-multiple-aggregations\">\n<span id=\"id1\"></span><h3>複数のアグリゲーションを統合する<a class=\"heading-anchor\" href=\"#combining-multiple-aggregations\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> を用いて複数の集計 (アグリゲーション) を統合することは、 <a class=\"extlink-ticket reference external\" href=\"https://code.djangoproject.com/ticket/10060\">誤った結果を生み出します</a> 。サブクエリの代わりに結合(JOIN)が使われるからです:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">book</span> <span class=\"o\">=</span> <span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">first</span><span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">book</span><span class=\"o\">.</span><span class=\"n\">authors</span><span class=\"o\">.</span><span class=\"n\">count</span><span class=\"p\">()</span>\n<span class=\"go\">2</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">book</span><span class=\"o\">.</span><span class=\"n\">store_set</span><span class=\"o\">.</span><span class=\"n\">count</span><span class=\"p\">()</span>\n<span class=\"go\">3</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">q</span> <span class=\"o\">=</span> <span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;authors&quot;</span><span class=\"p\">),</span> <span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;store&quot;</span><span class=\"p\">))</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">q</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">authors__count</span>\n<span class=\"go\">6</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">q</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">store__count</span>\n<span class=\"go\">6</span>\n</code></pre></div>\n<p>ほとんどの集計方法では、この問題を逃れるすべはありませんが、<a class=\"reference internal\" href=\"/ja/5.0/ref/models/querysets/#django.db.models.Count\" title=\"django.db.models.Count\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Count</span></code></a> では <code class=\"docutils literal notranslate\"><span class=\"pre\">distinct</span></code> が助けになります:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">q</span> <span class=\"o\">=</span> <span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;authors&quot;</span><span class=\"p\">,</span> <span class=\"n\">distinct</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">),</span> <span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;store&quot;</span><span class=\"p\">,</span> <span class=\"n\">distinct</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">q</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">authors__count</span>\n<span class=\"go\">2</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">q</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">store__count</span>\n<span class=\"go\">3</span>\n</code></pre></div>\n<aside class=\"admonition-if-in-doubt-inspect-the-sql-query admonition\">\n<p class=\"admonition-title\">疑わしい場合は、SQLクエリを調べてください！</p>\n<p>あなたのクエリ内で何が起こっているかを理解するために、あなたの <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> の <code class=\"docutils literal notranslate\"><span class=\"pre\">query</span></code> プロパティを調べることを検討してみてください。</p>\n</aside>\n</section>\n</section>\n<section id=\"joins-and-aggregates\">\n<h2>結合と集計方法<a class=\"heading-anchor\" href=\"#joins-and-aggregates\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>これまで、クエリ対象のモデルに属したフィールドに対する集計について扱ってきました。しかし、集計したい値が、クエリ対象のモデルのリレーション先のモデルに属している場合もあります。</p>\n<p>集計関数の中で、集計するフィールドを特定するとき、Django ではフィルタ内でリレーション先のフィールドを参照するために使われるのと同じ <a class=\"reference internal\" href=\"/ja/5.0/topics/db/queries/#field-lookups-intro\"><span class=\"std std-ref\">2重アンダースコア表記</span></a> が使えます。Django はリレーション先の値を取得し集計するために必要なテーブル結合を処理します。</p>\n<p>たとえば、各店舗で扱っている本の価格帯を調べるには、アノテーションを使います:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Max</span><span class=\"p\">,</span> <span class=\"n\">Min</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Store</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">min_price</span><span class=\"o\">=</span><span class=\"n\">Min</span><span class=\"p\">(</span><span class=\"s2\">&quot;books__price&quot;</span><span class=\"p\">),</span> <span class=\"n\">max_price</span><span class=\"o\">=</span><span class=\"n\">Max</span><span class=\"p\">(</span><span class=\"s2\">&quot;books__price&quot;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>これは、<code class=\"docutils literal notranslate\"><span class=\"pre\">Store</span></code> モデルを取得し、(many-to-many リレーションシップを通じて) <code class=\"docutils literal notranslate\"><span class=\"pre\">Book</span></code> モデルと結合し、そして書籍モデルの price フィールドの最大値と最小値を計算するように、Django に通知します。</p>\n<p>同じルールが <code class=\"docutils literal notranslate\"><span class=\"pre\">aggregate()</span></code> 句にも適用されます。もし、どこかのストアで販売されている本の最低価格と最高価格を知りたければ、集計が使えます。</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Store</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">aggregate</span><span class=\"p\">(</span><span class=\"n\">min_price</span><span class=\"o\">=</span><span class=\"n\">Min</span><span class=\"p\">(</span><span class=\"s2\">&quot;books__price&quot;</span><span class=\"p\">),</span> <span class=\"n\">max_price</span><span class=\"o\">=</span><span class=\"n\">Max</span><span class=\"p\">(</span><span class=\"s2\">&quot;books__price&quot;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>連結は必要ならいくつでもできます。たとえば、販売されている本の中で最も若い著者の年齢を抽出するには、次のようなクエリを発行します:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Store</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">aggregate</span><span class=\"p\">(</span><span class=\"n\">youngest_age</span><span class=\"o\">=</span><span class=\"n\">Min</span><span class=\"p\">(</span><span class=\"s2\">&quot;books__authors__age&quot;</span><span class=\"p\">))</span>\n</code></pre></div>\n<section id=\"following-relationships-backwards\">\n<h3>逆方向のリレーション<a class=\"heading-anchor\" href=\"#following-relationships-backwards\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><a class=\"reference internal\" href=\"/ja/5.0/topics/db/queries/#lookups-that-span-relationships\"><span class=\"std std-ref\">リレーションを横断するルックアップ</span></a> と似たように、モデルのフィールドやモデルのリレーションに関する集計は &quot;逆方向&quot; のリレーションを含むことができます。ここでも小文字にしたモデル名と2つのアンダースコアが用いられます。</p>\n<p>たとえば、すべての出版社にそれぞれの総書籍数カウンターのアノテーションを付けることができます（ <code class=\"docutils literal notranslate\"><span class=\"pre\">Publisher</span></code> -&gt; <code class=\"docutils literal notranslate\"><span class=\"pre\">Book</span></code> の逆引き外部キーホップを指定するために <code class=\"docutils literal notranslate\"><span class=\"pre\">'book'</span></code> を使用していることに注意してください）:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Avg</span><span class=\"p\">,</span> <span class=\"n\">Count</span><span class=\"p\">,</span> <span class=\"n\">Min</span><span class=\"p\">,</span> <span class=\"n\">Sum</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Publisher</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;book&quot;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>(<code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> に含まれる全ての <code class=\"docutils literal notranslate\"><span class=\"pre\">Publisher</span></code> には <code class=\"docutils literal notranslate\"><span class=\"pre\">book__count</span></code> という名前の属性が追加されます。)</p>\n<p>また、各出版社が管理している本のうち、最も古い本を教えてもらうこともできます:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Publisher</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">aggregate</span><span class=\"p\">(</span><span class=\"n\">oldest_pubdate</span><span class=\"o\">=</span><span class=\"n\">Min</span><span class=\"p\">(</span><span class=\"s2\">&quot;book__pubdate&quot;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>(結果は <code class=\"docutils literal notranslate\"><span class=\"pre\">'oldest_pubdate'</span></code> というキーで参照できるようになります。もしこのように別名を指定しなければ、キーの名前は <code class=\"docutils literal notranslate\"><span class=\"pre\">'book__pubdate__min'</span></code> のように長くなります。)</p>\n<p>これは外部キーだけに適用されるわけではありません。多対多のリレーションにも使えます。たとえば、すべての著者について、その著者が(共著で)執筆したすべての本を考慮した総ページ数のアノテーションを求めることができます (<code class=\"docutils literal notranslate\"><span class=\"pre\">Author</span></code> -&gt; <code class=\"docutils literal notranslate\"><span class=\"pre\">Book</span></code> の逆多対多のホップを指定するために <code class=\"docutils literal notranslate\"><span class=\"pre\">'book'</span></code> を使用していることに注意してください):</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Author</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">total_pages</span><span class=\"o\">=</span><span class=\"n\">Sum</span><span class=\"p\">(</span><span class=\"s2\">&quot;book__pages&quot;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>(<code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> に含まれる <code class=\"docutils literal notranslate\"><span class=\"pre\">Author</span></code> は <code class=\"docutils literal notranslate\"><span class=\"pre\">total_pages</span></code> 属性を持ちます。別名が指定されなければ、 <code class=\"docutils literal notranslate\"><span class=\"pre\">book__pages__sum</span></code> のようになります。)</p>\n<p>また、現在登録されている著者の全書籍の平均評価を求めることもできます:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Author</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">aggregate</span><span class=\"p\">(</span><span class=\"n\">average_rating</span><span class=\"o\">=</span><span class=\"n\">Avg</span><span class=\"p\">(</span><span class=\"s2\">&quot;book__rating&quot;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>(結果は <code class=\"docutils literal notranslate\"><span class=\"pre\">average_rating</span></code> 属性を持ちます。別名が指定されなければ、 <code class=\"docutils literal notranslate\"><span class=\"pre\">book__rating__avg</span></code> のように長くなります。)</p>\n</section>\n</section>\n<section id=\"aggregations-and-other-queryset-clauses\">\n<h2>集計とその他の <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> 句<a class=\"heading-anchor\" href=\"#aggregations-and-other-queryset-clauses\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"filter-and-exclude\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">filter()</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">exclude()</span></code><a class=\"heading-anchor\" href=\"#filter-and-exclude\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>集計はフィルタと一緒に使うこともできます。通常のモデルフィールドに適用される全ての <code class=\"docutils literal notranslate\"><span class=\"pre\">filter()</span></code> (または <code class=\"docutils literal notranslate\"><span class=\"pre\">exclude()</span></code>) は集計に利用できるオブジェクトを構築します。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> 句と一緒に使うと、フィルタはアノテーションが計算されるオブジェクトを制限する効果があります。たとえば、&quot;Django&quot; で始まるタイトルを持つすべての書籍のアノテーションリストをクエリを使って生成できます:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Avg</span><span class=\"p\">,</span> <span class=\"n\">Count</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">name__startswith</span><span class=\"o\">=</span><span class=\"s2\">&quot;Django&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">num_authors</span><span class=\"o\">=</span><span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;authors&quot;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">aggregate()</span></code> 句と一緒に使うと、フィルタは集計を計算するオブジェクトを制限する効果があります。たとえば、&quot;Django&quot; で始まるタイトルの本の平均価格をクエリで求めることができます:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">name__startswith</span><span class=\"o\">=</span><span class=\"s2\">&quot;Django&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">aggregate</span><span class=\"p\">(</span><span class=\"n\">Avg</span><span class=\"p\">(</span><span class=\"s2\">&quot;price&quot;</span><span class=\"p\">))</span>\n</code></pre></div>\n<section id=\"filtering-on-annotations\">\n<span id=\"id2\"></span><h4>アノテーションのフィルタリング<a class=\"heading-anchor\" href=\"#filtering-on-annotations\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>アノテーションされた値もフィルタリングできます。アノテーションのエイリアスは他のモデルフィールドと同じように <code class=\"docutils literal notranslate\"><span class=\"pre\">filter()</span></code> 節や <code class=\"docutils literal notranslate\"><span class=\"pre\">exclude()</span></code> 句で使うことができます。</p>\n<p>たとえば、複数の著者を持つ書籍のリストを作成するには、次のクエリを発行します:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">num_authors</span><span class=\"o\">=</span><span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;authors&quot;</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">num_authors__gt</span><span class=\"o\">=</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>このクエリはアノテーション付きの結果セットを生成し、そのアノテーションに基づいてフィルタを生成します。</p>\n<p>もし2つのアノテーションを別々のフィルタで付ける必要がある場合は、 <code class=\"docutils literal notranslate\"><span class=\"pre\">filter</span></code> 引数を任意の集計で使うことができます。たとえば、評価の高い書籍のカウントを持つ著者のリストを生成する場合は、以下のようにします。</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">highly_rated</span> <span class=\"o\">=</span> <span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;book&quot;</span><span class=\"p\">,</span> <span class=\"nb\">filter</span><span class=\"o\">=</span><span class=\"n\">Q</span><span class=\"p\">(</span><span class=\"n\">book__rating__gte</span><span class=\"o\">=</span><span class=\"mi\">7</span><span class=\"p\">))</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Author</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">num_books</span><span class=\"o\">=</span><span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;book&quot;</span><span class=\"p\">),</span> <span class=\"n\">highly_rated_books</span><span class=\"o\">=</span><span class=\"n\">highly_rated</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>結果セットの各 <code class=\"docutils literal notranslate\"><span class=\"pre\">Author</span></code> は <code class=\"docutils literal notranslate\"><span class=\"pre\">num_books</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">highly_rated_books</span></code> 属性を持ちます。<a class=\"reference internal\" href=\"/ja/5.0/ref/models/conditional-expressions/#conditional-aggregation\"><span class=\"std std-ref\">条件付きの集計</span></a> も参照してください。</p>\n<aside class=\"admonition-choosing-between-filter-and-queryset-filter admonition\">\n<p class=\"admonition-title\"><code class=\"docutils literal notranslate\"><span class=\"pre\">filter</span></code> 引数と <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.filter()</span></code> のどちらを使うか？</p>\n<p>単一のアノテーションや集計で <code class=\"docutils literal notranslate\"><span class=\"pre\">filter</span></code> 引数を使用することは避けてください。 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet.filter()</span></code> を使用して行を除外する方が効率的です。集計の <code class=\"docutils literal notranslate\"><span class=\"pre\">filter</span></code> 引数は、同じリレーションに対して異なる条件で2つ以上の集計を行う場合にだけ有効です。</p>\n</aside>\n</section>\n<section id=\"order-of-annotate-and-filter-clauses\">\n<h4><code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> 句と <code class=\"docutils literal notranslate\"><span class=\"pre\">filter()</span></code> 句の順番<a class=\"heading-anchor\" href=\"#order-of-annotate-and-filter-clauses\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">filter()</span></code> の両方の句を含む複雑なクエリを開発する場合は、 <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> に適用する順番に特に注意してください。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> 句がクエリに適用されると、アノテーションはアノテーションが要求された時点までのクエリの状態に対して計算されます。これは、<code class=\"docutils literal notranslate\"><span class=\"pre\">filter()</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> は可換な演算ではないことを意味します。</p>\n<p>以下のことを仮定します。</p>\n<ul class=\"simple\">\n<li><p>出版社Aの本は2冊あり、評価は4と5である。</p></li>\n<li><p>出版社Bの本は2冊あり、評価は1と4である。</p></li>\n<li><p>出版社Cの本は1冊あり、評価は1である。</p></li>\n</ul>\n<p>以下は <code class=\"docutils literal notranslate\"><span class=\"pre\">Count</span></code> 集計を使った例です:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span> <span class=\"o\">=</span> <span class=\"n\">Publisher</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">num_books</span><span class=\"o\">=</span><span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;book&quot;</span><span class=\"p\">,</span> <span class=\"n\">distinct</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">book__rating__gt</span><span class=\"o\">=</span><span class=\"mf\">3.0</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">num_books</span>\n<span class=\"go\">(&lt;Publisher: A&gt;, 2)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"o\">.</span><span class=\"n\">num_books</span>\n<span class=\"go\">(&lt;Publisher: B&gt;, 2)</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span> <span class=\"o\">=</span> <span class=\"n\">Publisher</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">book__rating__gt</span><span class=\"o\">=</span><span class=\"mf\">3.0</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">num_books</span><span class=\"o\">=</span><span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;book&quot;</span><span class=\"p\">))</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">num_books</span>\n<span class=\"go\">(&lt;Publisher: A&gt;, 2)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"o\">.</span><span class=\"n\">num_books</span>\n<span class=\"go\">(&lt;Publisher: B&gt;, 1)</span>\n</code></pre></div>\n<p>どちらのクエリも、レーティングが3.0を超える本を少なくとも1冊持っている出版社のリストを返すので、出版社Cは除外されます。</p>\n<p>最初のクエリでは、アノテーションをフィルタよりも先に付けるため、フィルタはアノテーションに影響を与えません。 <code class=\"docutils literal notranslate\"><span class=\"pre\">distinct=True</span></code> は <a class=\"reference internal\" href=\"#combining-multiple-aggregations\"><span class=\"std std-ref\">クエリのバグ</span></a> を避けるために必要です。</p>\n<p>2つ目のクエリは、出版社ごとにレーティングが3.0を超える書籍の数をカウントします。フィルタはアノテーションより先にあるので、フィルタはアノテーションを計算するときに考慮されるオブジェクトを制限します。</p>\n<p>これは <code class=\"docutils literal notranslate\"><span class=\"pre\">Avg</span></code> 集計を使った別の例です:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span> <span class=\"o\">=</span> <span class=\"n\">Publisher</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">avg_rating</span><span class=\"o\">=</span><span class=\"n\">Avg</span><span class=\"p\">(</span><span class=\"s2\">&quot;book__rating&quot;</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">book__rating__gt</span><span class=\"o\">=</span><span class=\"mf\">3.0</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">avg_rating</span>\n<span class=\"go\">(&lt;Publisher: A&gt;, 4.5)  # (5+4)/2</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"o\">.</span><span class=\"n\">avg_rating</span>\n<span class=\"go\">(&lt;Publisher: B&gt;, 2.5)  # (1+4)/2</span>\n\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span> <span class=\"o\">=</span> <span class=\"n\">Publisher</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">book__rating__gt</span><span class=\"o\">=</span><span class=\"mf\">3.0</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"n\">avg_rating</span><span class=\"o\">=</span><span class=\"n\">Avg</span><span class=\"p\">(</span><span class=\"s2\">&quot;book__rating&quot;</span><span class=\"p\">)</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">avg_rating</span>\n<span class=\"go\">(&lt;Publisher: A&gt;, 4.5)  # (5+4)/2</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">b</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"o\">.</span><span class=\"n\">avg_rating</span>\n<span class=\"go\">(&lt;Publisher: B&gt;, 4.0)  # 4/1 (book with rating 1 excluded)</span>\n</code></pre></div>\n<p>最初のクエリは、3.0を超える評価を1冊でも持つ出版社の全書籍の平均評価を求めるものです。2つ目のクエリは、3.0を超えるレーティングを持つ出版社のみについて、その出版社の書籍のレーティングの平均を求めるものです。</p>\n<p>ORMが複雑なクエリセットをSQLクエリに変換する方法を直感的に理解するのは難しいので、疑問がある場合は <code class=\"docutils literal notranslate\"><span class=\"pre\">str(QuerySet.query)</span></code> でSQLを検査し、たくさんのテストを書いてください。</p>\n</section>\n</section>\n<section id=\"order-by\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">order_by()</span></code><a class=\"heading-anchor\" href=\"#order-by\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>アノテーションは、ソートの基準として使うことができます。 <code class=\"docutils literal notranslate\"><span class=\"pre\">order_by()</span></code> 句を定義すると、クエリの <code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> 句の中で定義されたエイリアスを参照できます。</p>\n<p>たとえば、本の <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> をその本に貢献した著者の数でソートするには、次のようなクエリを使います:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">num_authors</span><span class=\"o\">=</span><span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;authors&quot;</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"s2\">&quot;num_authors&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"values\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">values()</span></code><a class=\"heading-anchor\" href=\"#values\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>通常、アノテーションはオブジェクトごとに生成されます。アノテーションを付けた <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> は、元の <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> の各オブジェクトに対して1つの結果を返します。しかし、 <code class=\"docutils literal notranslate\"><span class=\"pre\">values()</span></code> 句を使って結果セットで返されるカラムを制限している場合は、アノテーションを付けるしくみが少し異なります。元の <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> の各結果に対してアノテーションを付ける代わりに、元の結果は <code class=\"docutils literal notranslate\"><span class=\"pre\">values()</span></code> 句で指定されたフィールドの一意な組み合わせに従ってグループ化されます。アノテーションはグループのすべてのメンバに対して計算されます。</p>\n<p>たとえば、各著者が書いた本の平均評価を調べるための Author へのクエリを考えてみましょう:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Author</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">average_rating</span><span class=\"o\">=</span><span class=\"n\">Avg</span><span class=\"p\">(</span><span class=\"s2\">&quot;book__rating&quot;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>これは、データベース内の各著者について、その本の平均評価をアノテーションした結果を1つ返します。</p>\n<p>しかし、 <code class=\"docutils literal notranslate\"><span class=\"pre\">values()</span></code> 句を使うと結果は少し違ってきます:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Author</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">values</span><span class=\"p\">(</span><span class=\"s2\">&quot;name&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">average_rating</span><span class=\"o\">=</span><span class=\"n\">Avg</span><span class=\"p\">(</span><span class=\"s2\">&quot;book__rating&quot;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>この例では、著者は名前によってグループ化されるので、それぞれの <em>一意な</em> 著者名に対してのみアノテーションを付けた結果が得られます。つまり、同じ名前の著者が2人いる場合、それらの結果はクエリの出力で1つの結果にマージされます。平均は両方の著者が書いた本の平均として計算されます。</p>\n<section id=\"order-of-annotate-and-values-clauses\">\n<h4><code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> 句と <code class=\"docutils literal notranslate\"><span class=\"pre\">values()</span></code> 句の順番<a class=\"heading-anchor\" href=\"#order-of-annotate-and-values-clauses\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">filter()</span></code> 句と同様に、<code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">values()</span></code> 句をクエリに適用する順序は重要です。もし <code class=\"docutils literal notranslate\"><span class=\"pre\">values()</span></code> 句が <code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> より先に来る場合、注釈は <code class=\"docutils literal notranslate\"><span class=\"pre\">values()</span></code> 句によって記述されたグルーピングを使用して計算されます。</p>\n<p>しかし、 <code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> 句が <code class=\"docutils literal notranslate\"><span class=\"pre\">values()</span></code> 句より先に来る場合、注釈はクエリセット全体に対して生成されます。この場合、 <code class=\"docutils literal notranslate\"><span class=\"pre\">values()</span></code> 句は出力されるフィールドを制限するだけです。</p>\n<p>たとえば、先ほどの例の <code class=\"docutils literal notranslate\"><span class=\"pre\">values()</span></code> 句と <code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> 句の順番を逆にすると、次のようになります:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Author</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">average_rating</span><span class=\"o\">=</span><span class=\"n\">Avg</span><span class=\"p\">(</span><span class=\"s2\">&quot;book__rating&quot;</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">values</span><span class=\"p\">(</span>\n<span class=\"gp\">... </span>    <span class=\"s2\">&quot;name&quot;</span><span class=\"p\">,</span> <span class=\"s2\">&quot;average_rating&quot;</span>\n<span class=\"gp\">... </span><span class=\"p\">)</span>\n</code></pre></div>\n<p>これで各著者に対して一意な結果が得られるようになりました。しかし、出力データには著者名と <code class=\"docutils literal notranslate\"><span class=\"pre\">average_rating</span></code> のアノテーションのみが返されます。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">average_rating</span></code> が返される値のリストに明示的に含まれていることにも注意してください。これは、<code class=\"docutils literal notranslate\"><span class=\"pre\">values()</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> 句の順序によるものです。</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">values()</span></code> 句が <code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> 句より先にある場合、アノテーションは結果セットに自動的に追加されます。しかし、 <code class=\"docutils literal notranslate\"><span class=\"pre\">values()</span></code> 句を <code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> 句の後に適用する場合は、集計列を明示的に含める必要があります。</p>\n</section>\n<section id=\"interaction-with-order-by\">\n<span id=\"aggregation-ordering-interaction\"></span><h4><code class=\"docutils literal notranslate\"><span class=\"pre\">order_by()</span></code> と一緒に使う<a class=\"heading-anchor\" href=\"#interaction-with-order-by\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>クエリセットの <code class=\"docutils literal notranslate\"><span class=\"pre\">order_by()</span></code> 部分で言及されたフィールドは、 <code class=\"docutils literal notranslate\"><span class=\"pre\">values()</span></code> 呼び出しで特に指定されていなくても、出力データの選択時に使用されます。これらの追加フィールドは &quot;同じような&quot; 結果をグループ化するため、同じ結果の行が別々の行に見えることがあります。これは特に、何かを数えるときに顕著に現れます。</p>\n<p>たとえば、次のようなモデルがあるとします:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">models</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Item</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">)</span>\n    <span class=\"n\">data</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">IntegerField</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>それぞれの <code class=\"docutils literal notranslate\"><span class=\"pre\">data</span></code> 値が、並べ替えられたクエリセットに何回現れるかを数えたい場合は、次のようにします:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">items</span> <span class=\"o\">=</span> <span class=\"n\">Item</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"s2\">&quot;name&quot;</span><span class=\"p\">)</span>\n<span class=\"c1\"># Warning: not quite correct!</span>\n<span class=\"n\">items</span><span class=\"o\">.</span><span class=\"n\">values</span><span class=\"p\">(</span><span class=\"s2\">&quot;data&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;id&quot;</span><span class=\"p\">))</span>\n</code></pre></div>\n<p>...これは <code class=\"docutils literal notranslate\"><span class=\"pre\">Item</span></code> オブジェクトを共通の <code class=\"docutils literal notranslate\"><span class=\"pre\">data</span></code> 値でグループ化し、各グループの <code class=\"docutils literal notranslate\"><span class=\"pre\">id</span></code> 値の数をカウントします。ただし、これはうまくいきません。 <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> によるソートもグループ化に影響するため、このクエリは <code class=\"docutils literal notranslate\"><span class=\"pre\">(data,</span> <span class=\"pre\">name)</span></code> のペアをグループ化することになります。代わりに、次のようなクエリセットを作成する必要があります:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"n\">items</span><span class=\"o\">.</span><span class=\"n\">values</span><span class=\"p\">(</span><span class=\"s2\">&quot;data&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;id&quot;</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>...このようにクエリ内のソートをクリアします。たとえば、 <code class=\"docutils literal notranslate\"><span class=\"pre\">data</span></code> で並べ替えることもできますが、これはすでにクエリで役割を果たしているため、害はありません。</p>\n<p>この動作は、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/querysets/#django.db.models.query.QuerySet.distinct\" title=\"django.db.models.query.QuerySet.distinct\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">distinct()</span></code></a> のクエリセットドキュメントで指摘されているのと同じで、一般的なルールも同じです。通常、結果に余分な列が影響を与えることは期待されないため、順序付けをクリアするか、少なくとも <code class=\"docutils literal notranslate\"><span class=\"pre\">values()</span></code> 呼び出しで選択するフィールドにのみ制限されていることを確認してください。</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">注釈</p>\n<p>なぜ Django が余分な列を削除しないのか、合理的に疑問に思うかもしれません。主な理由は、 <code class=\"docutils literal notranslate\"><span class=\"pre\">distinct()</span></code> やその他の場所との一貫性にあります。Django は、あなたが指定した順序付けの制約を <strong>決して</strong> 削除しません（そして、これらの他の方法の振る舞いを変更することは、私たちの <a class=\"reference internal\" href=\"/ja/5.0/misc/api-stability/\"><span class=\"doc\">API の安定性</span></a> ポリシーに違反するため、できません）。</p>\n</aside>\n</section>\n</section>\n<section id=\"aggregating-annotations\">\n<h3>アノテーションを集計する<a class=\"heading-anchor\" href=\"#aggregating-annotations\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>アノテーションの結果に対して集計を生成することもできます。<code class=\"docutils literal notranslate\"><span class=\"pre\">aggregate()</span></code> 句を定義するとき、提供する集計はクエリ内の <code class=\"docutils literal notranslate\"><span class=\"pre\">annotate()</span></code> 句の一部として定義された任意のエイリアスを参照できます。</p>\n<p>たとえば、1冊あたりの著者数の平均を計算したい場合、まず著者数をアノテーション付きで本のセットに追加し、その後、アノテーションフィールドを参照して著者数を集計します。</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Avg</span><span class=\"p\">,</span> <span class=\"n\">Count</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">annotate</span><span class=\"p\">(</span><span class=\"n\">num_authors</span><span class=\"o\">=</span><span class=\"n\">Count</span><span class=\"p\">(</span><span class=\"s2\">&quot;authors&quot;</span><span class=\"p\">))</span><span class=\"o\">.</span><span class=\"n\">aggregate</span><span class=\"p\">(</span><span class=\"n\">Avg</span><span class=\"p\">(</span><span class=\"s2\">&quot;num_authors&quot;</span><span class=\"p\">))</span>\n<span class=\"go\">{&#39;num_authors__avg&#39;: 1.66}</span>\n</code></pre></div>\n</section>\n<section id=\"aggregating-on-empty-querysets-or-groups\">\n<h3>空のクエリセットまたはグループでの集計<a class=\"heading-anchor\" href=\"#aggregating-on-empty-querysets-or-groups\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>集計が空のクエリセットやグループに適用された場合、結果のデフォルトは通常「None」となる <a class=\"reference internal\" href=\"/ja/5.0/ref/models/querysets/#aggregate-default\"><span class=\"std std-ref\">default</span></a> パラメータになります。この動作は、実行されたクエリが行を返さない場合に集計関数が「NULL」を返すために発生します。</p>\n<p>ほとんどの集計では、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/querysets/#aggregate-default\"><span class=\"std std-ref\">default</span></a> 引数を渡すことで戻り値を指定できます。しかし、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/querysets/#django.db.models.Count\" title=\"django.db.models.Count\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Count</span></code></a> は <a class=\"reference internal\" href=\"/ja/5.0/ref/models/querysets/#aggregate-default\"><span class=\"std std-ref\">default</span></a> 引数をサポートしていないため、空のクエリセットやグループに対しては常に <code class=\"docutils literal notranslate\"><span class=\"pre\">0</span></code> を返します。</p>\n<p>たとえば、書籍名に <em>web</em> を含む書籍がないと仮定して、この書籍セットの合計金額を計算すると、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/querysets/#django.db.models.Sum\" title=\"django.db.models.Sum\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Sum</span></code></a> 集計を計算する一致する行がないため、 <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> を返します:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Sum</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">name__contains</span><span class=\"o\">=</span><span class=\"s2\">&quot;web&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">aggregate</span><span class=\"p\">(</span><span class=\"n\">Sum</span><span class=\"p\">(</span><span class=\"s2\">&quot;price&quot;</span><span class=\"p\">))</span>\n<span class=\"go\">{&quot;price__sum&quot;: None}</span>\n</code></pre></div>\n<p>しかし、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/querysets/#django.db.models.Sum\" title=\"django.db.models.Sum\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Sum</span></code></a> を呼び出す際に <a class=\"reference internal\" href=\"/ja/5.0/ref/models/querysets/#aggregate-default\"><span class=\"std std-ref\">default</span></a> 引数を指定することで、本が見つからない場合に異なるデフォルト値を返すことができます:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">name__contains</span><span class=\"o\">=</span><span class=\"s2\">&quot;web&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">aggregate</span><span class=\"p\">(</span><span class=\"n\">Sum</span><span class=\"p\">(</span><span class=\"s2\">&quot;price&quot;</span><span class=\"p\">,</span> <span class=\"n\">default</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">))</span>\n<span class=\"go\">{&quot;price__sum&quot;: Decimal(&quot;0&quot;)}</span>\n</code></pre></div>\n<p>内部では、 <a class=\"reference internal\" href=\"/ja/5.0/ref/models/querysets/#aggregate-default\"><span class=\"std std-ref\">default</span></a> 引数は、集計関数を <a class=\"reference internal\" href=\"/ja/5.0/ref/models/database-functions/#django.db.models.functions.Coalesce\" title=\"django.db.models.functions.Coalesce\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">Coalesce</span></code></a> でラップすることによって実装されています。</p>\n</section>\n</section>","rootId":"aggregation","toc":[{"title":"チートシート","anchor":"cheat-sheet","children":[]},{"title":"QuerySet に対して集計を生成する","anchor":"generating-aggregates-over-a-queryset","children":[]},{"title":"QuerySet の各アイテムに対する集計を生成する","anchor":"generating-aggregates-for-each-item-in-a-queryset","children":[{"title":"複数のアグリゲーションを統合する","anchor":"combining-multiple-aggregations","children":[]}]},{"title":"結合と集計方法","anchor":"joins-and-aggregates","children":[{"title":"逆方向のリレーション","anchor":"following-relationships-backwards","children":[]}]},{"title":"集計とその他の QuerySet 句","anchor":"aggregations-and-other-queryset-clauses","children":[{"title":"filter() と exclude()","anchor":"filter-and-exclude","children":[{"title":"アノテーションのフィルタリング","anchor":"filtering-on-annotations","children":[]},{"title":"annotate() 句と filter() 句の順番","anchor":"order-of-annotate-and-filter-clauses","children":[]}]},{"title":"order_by()","anchor":"order-by","children":[]},{"title":"values()","anchor":"values","children":[{"title":"annotate() 句と values() 句の順番","anchor":"order-of-annotate-and-values-clauses","children":[]},{"title":"order_by() と一緒に使う","anchor":"interaction-with-order-by","children":[]}]},{"title":"アノテーションを集計する","anchor":"aggregating-annotations","children":[]},{"title":"空のクエリセットまたはグループでの集計","anchor":"aggregating-on-empty-querysets-or-groups","children":[]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Django を使う","url":"/ja/5.0/topics/"},{"docname":"topics/db/index","title":"モデルとデータベース","url":"/ja/5.0/topics/db/"}],"prev":{"docname":"topics/db/queries","title":"クエリを作成する","url":"/ja/5.0/topics/db/queries/"},"next":{"docname":"topics/db/search","title":"検索","url":"/ja/5.0/topics/db/search/"},"formats":{"html":"/ja/5.0/topics/db/aggregation/","markdown":"/ja/5.0/topics/db/aggregation.md","json":"/ja/5.0/topics/db/aggregation.json"},"source":"https://github.com/django/django/blob/stable/5.0.x/docs/topics/db/aggregation.txt","official":"https://docs.djangoproject.com/ja/5.0/topics/db/aggregation/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}