SQL 集計関数 - SUM、MIN、MAX、AVG、COUNT。 SQL での計算 計算フィールドの作成

SQL - レッスン 8. レコードのグループ化と COUNT() 関数

どのようなメッセージがあり、どのようなトピックがあるのか​​を思い出してみましょう。 これを行うには、通常のクエリを使用できます。

フォーラムにあるメッセージの数を調べる必要がある場合はどうなるでしょうか。 これを行うには、組み込み関数を使用できます カウント()。 この関数は行数をカウントします。 さらに、* がこの関数の引数として使用される場合、テーブルのすべての行がカウントされます。 また、列名が引数として指定された場合は、指定された列に値を持つ行のみがカウントされます。

この例では、両方の引数が同じ結果を返します。 すべてのテーブル列は NOT NULL です。 id_topic 列を引数として使用してクエリを作成してみましょう。

投稿から COUNT(id_topic) を選択します。

したがって、トピックには 4 つのメッセージがあります。 しかし、各トピックに投稿が何件あるかを知りたい場合はどうすればよいでしょうか。 これを行うには、メッセージをトピックごとにグループ化し、各グループのメッセージ数を計算する必要があります。 SQL でグループ化するには、演算子を使用します グループ化。 リクエストは次のようになります。

SELECT id_topic, COUNT(id_topic) FROM 投稿から GROUP BY id_topic;

オペレーター グループ化これは DBMS に、id_topic 列でデータをグループ化し (つまり、各トピックは別個のグループです)、各グループの行数をカウントするように指示します。

id=1 のトピックには 3 つのメッセージがあり、id=4 には 1 つのメッセージがあります。 ちなみに、id_topic フィールドに欠損値が存在する可能性がある場合、そのような行は値が NULL の別のグループに結合されます。

3 つ以上のメッセージを持つグループのみに興味があると仮定しましょう。 通常のクエリでは、演算子を使用して条件を指定します。 どこただし、この演算子は文字列のみを操作でき、グループの場合は同じ機能が演算子によって実行されます。 持っている:

SELECT id_topic, COUNT(id_topic) FROM 投稿 GROUP BY id_topic HAVING COUNT(id_topic) > 2;

その結果、次のようになります。

レッスン 4 では、オペレーターが設定できる条件を検討しました。 どこ、オペレータによって同じ条件を指定できます。 持っている、それを覚えておいてください。 どこ文字列をフィルタリングし、 持っている- グループ。

そこで今日は、グループを作成する方法と、テーブルおよびグループ内の行数をカウントする方法を学びました。 基本的にはオペレーターと一緒に グループ化他の組み込み関数を使用することもできますが、それらについては後で学習します。

要約することを学びましょう。 いいえ、これらは SQL を学習した結果ではなく、データベース テーブルの列の値の結果です。 SQL 集計関数は、列の値を操作して単一の結果値を生成します。 最も一般的に使用される SQL 集計関数は、SUM、MIN、MAX、AVG、および COUNT です。 集計関数を使用する 2 つのケースを区別する必要があります。 まず、集計関数は単独で使用され、単一の結果値を返します。 次に、集計関数は SQL GROUP BY 句で使用されます。つまり、フィールド (列) ごとにグループ化して、各グループの結果の値を取得します。 まず、グループ化せずに集計関数を使用する場合を考えてみましょう。

SQL SUM関数

SQL SUM 関数は、データベース テーブルの列の値の合計を返します。 値が数値である列にのみ適用できます。 結果の合計を取得する SQL クエリは次のように始まります。

SELECT SUM (COLUMN_NAME) ...

この式の後に FROM (TABLE_NAME) が続き、WHERE 句を使用して条件を指定できます。 さらに、列名の前に DISTINCT を付けることができます。これは、一意の値のみがカウントされることを意味します。 デフォルトでは、すべての値が考慮されます (このために、DISTINCT ではなく ALL を具体的に指定できますが、ALL という単語は必要ありません)。

例1.会社のデータベースには、部門と従業員に関するデータが含まれています。 Staff テーブルには、従業員の給与に関するデータを含む列もあります。 テーブルからの選択は次のようになります (画像を拡大するには、マウスの左ボタンでクリックします)。

すべての給与の合計を取得するには、次のクエリを使用します。

スタッフから SUM (給与) を選択してください

このクエリは値 287664.63 を返します。

そしていま 。 演習ではすでにタスクを複雑にし始めており、実際に遭遇するタスクに近づけています。

SQL MIN 関数

SQL MIN 関数は、値が数値である列に対しても動作し、列内のすべての値の最小値を返します。 この関数の構文は SUM 関数と似ています。

例 3.データベースとテーブルは例 1 と同じです。

部門番号 42 の従業員の最低賃金を調べる必要があります。これを行うには、次のリクエストを作成します。

クエリは値 10505.90 を返します。

そしてまた 独立した解決策の演習。 この演習および他のいくつかの演習では、Staff テーブルだけでなく、会社の部門に関するデータを含む Org テーブルも必要になります。


例4. Org テーブルが Staff テーブルに追加され、会社の部門に関するデータが含まれます。 ボストンにある部門の 1 人の従業員の最小勤務年数を出力します。

SQL MAX関数

SQL MAX 関数は同様に機能し、同様の構文を持ち、列内のすべての値の最大値を決定する必要がある場合に使用されます。

例5。

部門番号 42 の従業員の最高給与を調べる必要があります。これを行うには、次のリクエストを作成します。

クエリは値 18352.80 を返します。

時間です 独立した解決策のための演習.

例6。ここでも、Staff と Org という 2 つのテーブルを使用して作業します。 部門名と部門グループ(部門)東部に属する部門の従業員1名が受け取るコミッションの最大値を表示します。 使用 JOIN (テーブルの結合) .

SQL AVG 関数

前述の関数の構文に関して述べられている内容は、SQL AVG 関数にも当てはまります。 この関数は、列内のすべての値の平均を返します。

例7。データベースとテーブルは前の例と同じです。

部門番号 42 の従業員の平均勤続年数を調べたいとします。これを行うには、次のクエリを作成します。

結果は6.33になります

例8。私たちは 1 つのテーブル、つまりスタッフで仕事をします。 経験年数 4 ~ 6 年の従業員の平均給与を表示します。

SQL COUNT 関数

SQL COUNT 関数は、データベース テーブル内のレコードの数を返します。 クエリで SELECT COUNT(COLUMN_NAME) ... を指定すると、結果は列の値が NULL (未定義) であるレコードを考慮しないレコード数になります。 アスタリスクを引数として使用して SELECT COUNT(*) ... クエリを開始すると、結果はテーブルのすべてのレコード (行) の数になります。

例9。データベースとテーブルは前の例と同じです。

コミッションを受け取っている全従業員の数を知りたいと考えています。 Comm 列の値が NULL ではない従業員の数は、次のクエリによって返されます。

スタッフから COUNT (通信) を選択

結果は11になります。

例10。データベースとテーブルは前の例と同じです。

テーブル内のレコードの総数を調べたい場合は、COUNT 関数の引数としてアスタリスクを含むクエリを使用します。

スタッフからカウント (*) を選択

結果は17になります。

次に、次で 独立した解決策の演習サブクエリを使用する必要があります。

例11.私たちは 1 つのテーブル、つまりスタッフで仕事をします。 企画部門(プレーンズ)の従業員数を表示します。

SQL GROUP BY を使用した集計関数

次に、集計関数を SQL GROUP BY ステートメントと組み合わせて使用​​する方法を見てみましょう。 SQL GROUP BY ステートメントは、データベース テーブル内の列ごとに結果値をグループ化するために使用されます。 ウェブサイトには、 このオペレーター専用のレッスン .

例12。広告ポータルのデータベースがあります。 これには、その週に送信された広告に関するデータを含む広告テーブルがあります。 カテゴリ列には大きな広告カテゴリ (不動産など) に関するデータが含まれ、パーツ列にはカテゴリに含まれる小さなパーツに関するデータが含まれます (たとえば、アパートと夏の家のパーツは不動産カテゴリの一部です)。 Units 列には送信された広告の数に関するデータが含まれ、Money 列には広告の送信に対して受け取った金額に関するデータが含まれます。

カテゴリー一部単位お金
輸送110 17600
不動産アパート89 18690
不動産ダーチャ57 11970
輸送オートバイ131 20960
建設資材ボード68 7140
電気工学テレビ127 8255
電気工学冷蔵庫137 8905
建設資材レジプス112 11760
レジャー96 6240
不動産自宅で47 9870
レジャー音楽117 7605
レジャーゲーム41 2665

SQL GROUP BY ステートメントを使用して、各カテゴリに広告を投稿することで得られた金額を調べます。 次のリクエストを書きます。

カテゴリを選択、広告からの金額として合計 (金額) カテゴリごとにグループ化

例13。データベースとテーブルは前の例と同じです。

SQL GROUP BY ステートメントを使用して、各カテゴリのどの部分に最も多くのリストが含まれているかを調べます。 次のリクエストを書きます。

SELECT カテゴリ、パーツ、MAX (ユニット) AS 最大値 FROM Ads GROUP BY カテゴリ

結果は次の表になります。

合計値と個別値を1つのテーブルで取得可能 UNION 演算子を使用してクエリ結果を結合する .

リレーショナル データベースと SQL 言語

次のようなリクエストがあります。

SELECT i.*、COUNT(*) AS 通貨、SUM(ig.quantity) AS 合計、SUM(g.price * ig.quantity) AS 価格、c.briefly AS cname FROM 請求書 AS i、invoice_goods AS ig、good g LEFT JOIN 通貨 c ON (c.id = g.currency) WHERE ig.invoice_id = i.id AND g.id = ig.good_id GROUP BY g.currency ORDER BY i.date DESC;

それらの。 注文のリストが選択され、さまざまな通貨で商品の合計コストが計算されます (通貨は商品に設定されており、結果の cname 列は通貨の名前です)。

通貨の結果列で同じ i.id を持つレコードの数を取得する必要がありますが、COUNT() パラメーターを試しても何も起こりませんでした。常に 1 が返されます。

質問: 通貨列の実際の値を取得することは可能ですか? それらの。 商品が 3 つの異なる通貨での価格で注文された場合、通貨 = 3 になりますか?

ただし、MySQL は SQL に関して自由度が高すぎます。 たとえば、この選択のコンテキストでは i.* は何を意味しますか? 請求書テーブルのすべての列? これらにはグループ関数が適用されないため、GROUP BY にリストされていれば便利ですが、そうしないと行をグループ化する原理が完全に明確になりません。 すべての注文のすべての商品を通貨ごとに受け取る必要がある場合と、注文ごとに通貨ごとにグループ化されたすべての商品を受け取る必要がある場合は、まったく異なります。
選択に基づいて、次のデータ構造を想定できます。
請求書テーブル:

Invoice_goods テーブル:

商品表:

通貨テーブル:

現在の選択は何を返しますか? 理論的には、この注文に商品が含まれている通貨ごとに、注文ごとに N 行が返されます。 しかし、g.currency 以外は group by で指定されていないため、これは明白ではありません :) さらに、 c.briefly 列も暗黙的なグループの形成に寄与します。 結果として、i.*、g.currency、および c.brieflies の一意の組み合わせごとに、SUM 関数と COUNT 関数が適用される行に対してグループが形成されます。 COUNT パラメータを操作した結果、常に 1 が得られたという事実は、結果のグループにレコードが 1 つしかなかったことを意味します (つまり、グループが必要に応じて形成されていません。要件を詳しく説明してもらえますか?)。 あなたの質問からは、あなたが知りたいこと、つまり注文に含まれた異なる通貨の数、または特定の通貨での注文の数が明確ではありません。 最初のケースでは、いくつかのオプションが可能ですが、すべて MySQL の機能に依存します。2 番目のケースでは、選択式を別の方法で記述する必要があります。

ただし、MySQL は SQL に関して自由度が高すぎます。 たとえば、この選択のコンテキストでは i.* は何を意味しますか? 請求書テーブルのすべての列?

はい、正確に。 しかし、これは大きな役割を果たしません。なぜなら... この場合、それらの中に有用な列はありません。 i.* を i.id とします。 具体的に言うと。

現在の選択は何を返しますか? 理論的には、この注文に商品が含まれる通貨ごとに、注文ごとに N 行が返されます。 しかし、group by では g.currency 以外は何も指定されていないため、これは明白ではありません:)、

その通り。
次のものが返されます (この例では、 i からすべての列ではなく id のみを選択します)。

ID通貨合計価格名前
33 1 1.00 198.00 BF
33 1 4.00 1548.04 こする
さらに、c.briefly 列も暗黙的なグループの形成に貢献します。

どうやって? テーブルは c.id=g.currency によって結合され、 g.currency によってグループ化されます。

COUNT パラメータを使用した結果、常に 1 が得られたという事実は、結果のグループにはレコードが 1 つしかなかったことを意味します。

いいえ、グループは以下から構築されました 1位記録。 私が理解している限り、COUNT() はこの理由で 1 を返します (結局のところ、グループ内で異なる列 (通貨列を除く) は集計関数によって作成されます)。

(つまり、グループが要求どおりに形成されません。要件を詳しく説明していただけますか?)。

必要に応じてグループを結成し、 各グループ --これ 各通貨の総商品コスト。 しかし、それ以外にも私は、 いくらかを計算する必要がありますまたは の要素これ グループ.

あなたの質問からは、あなたが知りたいこと、つまり注文に含まれた異なる通貨の数、または特定の通貨での注文の数が明確ではありません。

はい、少し忙しくなりました。 最初の 1 つだけです。

dmig[書類]
グループの形成に「暗黙的に」参加するとは、列が GROUP BY で指定されておらず、同時にグループ関数の引数でもない場合、選択の結果は次と同じになることを意味します。その列が GROUP BY で指定されていた場合はどうなるでしょうか。 あなたの選択と以下の選択はまったく同じ結果を生成します (結合には注意しないでください。結合を単一の記録形式にまとめただけです)。

i.id ID、count(*) 通貨、sum(ig.quantity) total、SUM(g.price * ig.quantity) 価格、c.briefly cname FROM invoice を選択して、invoice_goods ig on に参加します (ig.invoice_id = i. id) 結合良い g on (g.id = ig.good_id) LEFT OUTER JOIN 通貨 c ON (c.id = g.currency) i.id、c.briefly でグループ化

結果のサンプルの各行には、通貨が 1 つだけ存在することがわかります (通貨が異なる場合は、2 つの行が存在することになります)。 この場合、要素の数について話しているのでしょうか? オーダー商品について? この場合、あなたの選択は完全に正しいです。この通貨に関しては、この注文には 1 つの項目しかありません。
データスキーマを見てみましょう。

  1. 1回の注文でたくさんの商品(行)がありますよね?
  2. それぞれのアイテムはグッズディレクトリの商品ですよね?
  3. 各製品には特定の (そして 1 つのみの) 通貨があります。これは c.id = g.currency から導き出されますよね?

注文には何通貨ありますか? さまざまな通貨を使用したポイントがたくさんあります。
g.price * ig.quantity の追加は、1 つの通貨のポイントの場合にのみ意味を持ちます;) (ただし、キロメートルと時間を追加することもできます :) では、何があなたに合わないのか? 注文に含まれる異なる通貨の数が必要であると述べています
この場合、同じ選択のフレームワーク内であらゆる種類のトリックを使用せずにこれを実行しても (MySQL では実行できない可能性が高くなります)、機能しません;(
残念ながら、私は MySQL の専門家ではありません。 Oracle では 1 回の選択でこれを行うことができますが、このアドバイスは役に立ちますか? しそうにない;)

# 1回の注文で商品数(行数)が多くなりますよね?
# 各アイテムはグッズディレクトリの商品ですよね?
# 各製品には特定の (そして 1 つのみの) 通貨があります。これは c.id = g.currency から導き出されますよね?

それで。
1 つの注文: invoice テーブルの 1 つのレコード。invoice_goods の n(>0) レコードに対応し、それぞれのレコードが商品テーブルの 1 レコードに対応し、それぞれの「通貨」レコードが、通貨テーブルの最初のレコード ( LEFT JOIN - 曲がった手で通貨ディレクトリを編集する場合 - MyISAM のようなテーブルは外部キーをサポートしていません)。

注文には何通貨ありますか? さまざまな通貨を使用したポイントがたくさんあります。

はい、正確に。

g.price * ig.quantity の追加は、1 つの通貨のポイントの場合にのみ意味があります;) (ただし、時間を含むキロメートルも追加できます:)

このため、グループ化は通貨 ID (g.currency) によって行われます。

Oracle では 1 回の選択でこれを行うことができますが、このアドバイスは役に立ちますか?

M.b.
Oracle とは少し話したことがあり、pl/sql についてはよく知っています。

オプション1。

Select a.*, count(*) over (a.id で分割) 通貨 from (select i.id id, sum(ig.quantity) total, SUM(g.price * ig.quantity)price, c.briefly cname FROM 請求書 i は invoice_goods ig on (ig.invoice_id = i.id) に参加します (ig.id = ig.good_id) LEFT OUTER JOIN 通貨 c ON (c.id = g.currency) i.id によるグループ化、 c.簡単に)a

これはいわゆる 分析機能。 99% の確率で、MySQL では動作しません。

オプション #2。
たとえば countCurrency などの関数が作成され、この関数は注文 ID に基づいて、それに参加した通貨の数を返します。

i.id ID、countCurrency(i.id) 通貨、sum(ig.quantity) total、SUM(g.price * ig.quantity) 価格、c.briefly cname FROM invoice を選択して、invoice_goods ig on に参加します (ig.invoice_id = i.id) 結合良い g オン (g.id = ig.good_id) LEFT OUTER JOIN 通貨 c ON (c.id = g.currency) i.id、c.briefly、countCurrency(i.id) によるグループ化

それは機能するかもしれません...しかし、各注文の通貨ごとに呼び出されます。 MySQL で関数ごとに GROUP BY を実行できるかどうかはわかりません...

オプション No.3

i.id ID、agr.cnt 通貨、sum(ig.quantity) total、SUM(g.price * ig.quantity) 価格、c.briefly cname FROM invoice を選択して、invoice_goods ig on (ig.invoice_id = i.id) に参加します) 結合良好です (g.id = ig.good_id) LEFT OUTER JOIN 通貨 c ON (c.id = g.currency) 左外部結合 (select ii.id, count(distinct gg.currency) cnt from invoice ii, invoce_goods iig、good gg where ii.id = iig.invoice_id および gg.id = iig.good_id ii.id でグループ化) agr on (i.id = agr.id) i.id、c.briefly、agr でグループ化。 cnt

おそらく最も正しい...そしておそらくすべてのオプションの中で最も効果的なオプションです。

最も速いのはオプション No. 1 です。 2 番が最も効果的ではありません。 注文内の通貨が多いほど、カウントされる頻度も高くなります。
3 番も原理的には速度の点では最高ではありませんが、少なくとも DBMS 内のキャッシュに頼ることができます。

3 つすべてを選択した結果は次のようになります。

ID通貨合計価格名前
33 2 1.00 198.00 BF
33 2 4.00 1548.04 こする

同じ ID の場合、通貨列の数値は常に同じになります。これは必要ですか?

算術演算子の使用と計算列の構築について説明します。 最終的な (集計) 関数 COUNT、SUM、AVG、MAX、MIN が考慮されます。 データ選択クエリでグループ化するために GROUP BY 演算子を使用する例を示します。 HAVING 句の使用方法について説明します。

計算フィールドの構築

一般に、作成するには 計算された (導出された) フィールド SELECT リストには何らかの SQL 式が含まれている必要があります。 これらの式では、加算、減算、乗算、除算の算術演算と組み込み SQL 関数が使用されます。 テーブルまたはクエリの任意の列 (フィールド) の名前を指定できますが、使用できるのは、対応するステートメントの FROM 句リストにリストされているテーブルまたはクエリの列名のみです。 複雑な式を作成する場合、括弧が必要になる場合があります。

SQL 標準では、AS 句が使用される結果のテーブルの列の名前を明示的に指定できます。

Product.Name、Product.Price、Deal.Quantity、Product.Price*Deal.Quantity AS Costを選択します。 FROM Product INNER JOIN Deal ON Product.ProductCode=Deal.ProductCode 例6.1。 各トランザクションの合計コストの計算。

例6.2。顧客の姓とイニシャルを示す企業のリストを取得します。

会社、姓+""+ Left(名,1)+"."+Left(ミドルネーム,1)+"."AS クライアントからのフルネームを選択します 例6.2。 顧客の姓とイニシャルを示す企業のリストを取得します。

このリクエストでは組み込みの Left 関数が使用されており、この場合、テキスト変数の左から 1 文字を切り取ることができます。

例6.3。発売年月を示す商品リストを取得します。

SELECT Product.Name, Year(Transaction.Date) AS Year, Month(Transaction.Date) AS Month FROM Product INNER JOIN Transaction ON Product.ProductCode=Transaction.ProductCode 例6.3。 発売年月が記載された商品リストを受け取る。

このクエリでは、組み込み関数 Year および Month を使用して、日付から年と月を抽出します。

集計関数の使用

を使用することで 最終 (集計) 関数 SQL クエリ内で、出力セットの選択された値のセットに関する多くの一般的な統計情報を取得できます。

ユーザーは次の基本的な機能にアクセスできます。 要約関数:

  • カウント (式) - SQL クエリの出力セット内のレコードの数を決定します。
  • Min/Max (式) - 特定のリクエストフィールドの値のセットの最小値と最大値を決定します。
  • Avg (式) - この関数を使用すると、クエリによって選択されたレコードの特定のフィールドに保存されている一連の値の平均を計算できます。 これは算術平均です。 値の合計をその数値で割ったもの。
  • 合計 (式) - クエリによって選択されたレコードの特定のフィールドに含まれる値のセットの合計を計算します。

ほとんどの場合、列名は式として使用されます。 この式は、複数のテーブルの値を使用して計算することもできます。

これらの関数はすべて、テーブルの単一列の値または算術式を操作し、単一の値を返します。 COUNT 、 MIN 、 MAX 関数は数値フィールドと数値以外のフィールドの両方に適用されますが、 SUM 関数と AVG 関数は COUNT(*) を除き、数値フィールドにのみ使用できます。 関数の結果を計算する場合、最初にすべての null 値が削除され、その後、必要な操作が残りの特定の列の値にのみ適用されます。 COUNT(*) オプションは COUNT 関数の特別な使用例であり、その目的は、NULL、重複、その他の値が含まれているかどうかに関係なく、結果のテーブル内のすべての行をカウントすることです。

ジェネリック関数を使用する前に重複した値を削除する必要がある場合は、関数定義内の列名の前に DISTINCT キーワードを付ける必要があります。 MIN 関数と MAX 関数には意味がありませんが、これを使用すると SUM 関数と AVG 関数の結果に影響を与える可能性があるため、それぞれの場合に存在する必要があるかどうかを検討する必要があります。 また、DISTINCT キーワードは、どのクエリでも 1 回のみ指定できます。

非常に重要な点に注意してください。 要約関数は、SELECT 句のリスト内および HAVING 句の一部としてのみ使用できます。 他のすべての場合において、これは受け入れられません。 SELECT 句のリストに次のものが含まれる場合、 要約関数、クエリ テキストに、データをグループに結合するための GROUP BY 句が含まれていない場合、フィールドが引数として機能する場合を除き、SELECT 句のリスト要素にフィールドへの参照を含めることはできません。 最終関数.

例6.4。製品の最初のアルファベット名を決定します。

SELECT Min(Product.Name) AS Min_Name FROM Product 例6.4。 製品の最初のアルファベット名の決定。

例6.5。トランザクションの数を決定します。

SELECT Count(*) AS Number_of_deals FROM Deal 例6.5。 トランザクションの数を決定します。

例6.6。販売された商品の総数量を決定します。

SELECT Sum(Deal.quantity) AS item_quantity FROM Deal 例6.6。 販売された商品の総数量の決定。

例6.7。販売される商品の平均価格を決定します。

SELECT Avg(Product.Price) AS Avg_Price FROM Product INNER JOIN Deal ON Product.ProductCode=Deal.ProductCode; 例6.7。 販売される商品の平均価格の決定。

SELECT Sum(Product.Price*Transaction.Quantity) AS Cost FROM Product INNER JOIN Transaction ON Product.ProductCode=Transaction.ProductCode 例6.8。 販売された商品の総原価を計算します。

GROUP BY 句

クエリでは小計の生成が必要になることがよくありますが、これは通常、クエリ内に「for each...」という語句が出現することで示されます。 この目的のために、SELECT ステートメントで GROUP BY 句が使用されます。 GROUP BY を含むクエリは、SELECT 操作によって返されたデータをグループ化し、個々のグループごとに 1 つの概要行を作成するため、グループ化クエリと呼ばれます。 SQL 標準では、SELECT 句と GROUP BY 句が密接に関連していることが要求されます。 SELECT ステートメントに GROUP BY 句が含まれる場合、SELECT 句の各リスト要素にはグループ全体に対して 1 つの値が必要です。 さらに、SELECT 句には次のタイプの要素のみを含めることができます: フィールド名、 要約関数、上記の要素の組み合わせを含む定数と式。

SELECT 句にリストされているすべてのフィールド名は、列名が 最終関数。 逆の規則は当てはまりません。GROUP BY 句には、SELECT 句のリストにない列名が含まれる可能性があります。

WHERE 句を GROUP BY と組み合わせて使用​​すると、WHERE 句が最初に処理され、検索条件を満たす行のみがグループ化されます。

SQL 標準では、グループ化するときに、すべての欠損値が等しいものとして扱われると指定されています。 同じグループ化列内の 2 つのテーブル行に NULL 値が含まれており、他のすべての非 NULL グループ化列に同一の値が含まれている場合、それらは同じグループに配置されます。

例6.9。各顧客による平均購入量を計算します。

SELECT Client.LastName, Avg(Transaction.Quantity) AS Average_Quantity FROM Client INNER JOIN Trade ON Client.ClientCode=Transaction.ClientCode GROUP BY Client.LastName 例6.9。 各顧客による平均購入量を計算します。

「すべての顧客」というフレーズが文として SQL クエリに反映されます。 クライアントの姓によるグループ化.

例6.10。各製品がいくらで販売されたかを決定します。

SELECT Product.Name, Sum(Product.Price*Transaction.Quantity) AS Cost FROM Product INNER JOIN Deal ON Product.ProductCode=Transaction.ProductCode GROUP BY Product.Name 例6.10。 製品の各アイテムがいくらで販売されたかを決定します。

SELECT Client.Company, Count(Transaction.TransactionCode) AS Number_of_transactions FROM Client INNER JOIN Transaction ON Client.ClientCode=Transaction.ClientCode GROUP BY Client.Company 例6.11。 各企業が実行した取引の数をカウントします。

SELECT Customer.Company, Sum(Transaction.Quantity) AS Total_Quantity, Sum(Product.Price*Transaction.Quantity) AS Cost FROM Product INNER JOIN (Customer INNER JOIN Transaction ON Customer.ClientCode=Transaction.CustomerCode) ON Product.ProductCode=Transaction .製品コード GROUP BY Client.Company 例6.12。 各企業の商品の総購入量とそのコストを計算します。

例6.13。毎月の各製品の合計コストを決定します。

SELECT Product.Name, Month(Transaction.Date) AS Month, Sum(Product.Price*Transaction.Quantity) AS Cost FROM Product INNER JOIN Transaction ON Product.ProductCode=Transaction.ProductCode GROUP BY Product.Name, Month(Transaction.Date) ) 例6.13。 毎月の各製品の合計コストの決定。

例6.14。各月の各一流製品の合計コストを決定します。

SELECT Product.Name, Month(Transaction.Date) AS Month, Sum(Product.Price*Transaction.Quantity) AS Cost FROM Product INNER JOIN Transaction ON Product.ProductCode=Transaction.ProductCode WHERE Product.Grade="First" GROUP BY Product .名前、月(トランザクション.日付) 例6.14。 各月の各一流製品の合計コストの決定。

オファーあり

HAVING を使用すると、GROUP BY でグループ化され、HAVING で指定された条件を満たすすべてのデータ ブロックが反映されます。 これは、出力セットを「フィルタリング」するための追加オプションです。

HAVING の条件は WHERE の条件とは異なります。

  • HAVING は、結果のデータセットから集計値の結果を持つグループを除外します。
  • WHEREは条件を満たさないレコードをグループ化による集計値の計算から除外します。
  • WHERE検索条件に集計関数は指定できません。

例6.15。合計取引数が 3 件を超えた企業を特定します。

SELECT Client.Company, Count(Trade.Quantity) AS Number_of_deals FROM Client INNER JOIN Trade ON Client.ClientCode=Transaction.ClientCode GROUP BY Client.Company HAVING Count(Transaction.Quantity)>3 例6.15。 合計取引数が3件を超えた企業の特定。

例6.16。 10,000 ルーブル以上で販売された商品のリストを表示します。

SELECT Product.Name, Sum(Product.Price*Deal.Quantity) AS Cost FROM Product INNER JOIN Deal ON Product.ProductCode=Transaction.ProductCode GROUP BY Product.Name HAVING Sum(Product.Price*Deal.Quantity)>10000 例6.16。 10,000 ルーブル以上で販売された商品のリストを表示します。

例6.17。金額を指定せずに10,000以上で販売された商品のリストを表示します。

Product INNER JOIN Deal ON Product.ProductCode=Deal.ProductCode GROUP BY Product.Name HAVING Sum(Product.Price*Deal.Quantity)>10000 から Product.Name を選択します。 例6.17。 金額を指定せずに10,000以上で販売された商品のリストを表示します。

このチュートリアルでは、使用方法を学びます COUNT関数 SQL Server (Transact-SQL) の構文と例を説明します。

説明

SQL Server (Transact-SQL) の場合 COUNT関数結果セット内のフィールドまたは式の行数を返します。

構文

SQL Server (Transact-SQL) の COUNT 関数の構文は次のとおりです。

または、1 つ以上の列の結果をグループ化する場合の COUNT 関数の構文は次のとおりです。

パラメータまたは引数

式 1 、式 2 、… 式_n
COUNT 関数で囲まれていない式。SQL ステートメントの最後の GROUP BY 句に含める必要があります。
aggregate_expression は、NULL 以外の値がカウントされる列または式です。
tables - レコードを取得するテーブル。 FROM 句には少なくとも 1 つのテーブルがリストされている必要があります。
WHERE 条件 - オプション。 これらは、選択したレコードに対して満たさなければならない条件です。

NULL 以外の値を含む

誰もがこれを理解しているわけではありませんが、COUNT 関数は、COUNT の式 (aggregate_expression) の値が NULL ではないレコードのみをカウントします。 式に NULL 値が含まれる場合、その値は COUNT カウンターには含まれません。

COUNT 関数によって NULL 値がどのように評価されるかを示す COUNT 関数の例を見てみましょう。

たとえば、markets という次のテーブルがあるとします。

この COUNT の例では、クエリ結果セット内のすべてのmarket_id 値が NULL ではないため、3 が返されます。

ただし、COUNT 関数を使用する次の SELECT ステートメントを実行したとします。

トランザクション SQL

マーケットから COUNT(親孝行) を選択します。 --結果: 1

クエリ結果セット内の filials 値が NULL ではないため、この COUNT の例では 1 のみが返されます。 これは、filials = "yes" という最初の行になります。 これは、COUNT 関数の計算に含まれる唯一の行です。

応用

COUNT 関数は、次のバージョンの SQL Server (Transact-SQL) で使用できます。
SQL Server vNext、SQL Server 2016、SQL Server 2015、SQL Server 2014、SQL Server 2012、SQL Server 2008 R2、SQL Server 2008、SQL Server 2005

フィールドが 1 つある例

SQL Server (Transact-SQL) で COUNT 関数を使用する方法を理解するために、SQL Server COUNT 関数の例をいくつか見てみましょう。

たとえば、last_name = "Rasputin" のユーザーが持つ連絡先の数を確認できます。

この COUNT 関数の例では、COUNT (*) 式にエイリアス「連絡先の数」を指定しました。 したがって、結果セットにはフィールド名として「連絡先の数」が表示されます。

DISTINCT を使用した例

COUNT 関数では DISTINCT 演算子を使用できます。 たとえば、次の SQL ステートメントは、少なくとも 1 人の従業員が first_name = 'Samvel' である一意の部門の数を返します。