カテゴリ:

クエリ構文

QUALIFY

SELECT ステートメントでは、 QUALIFY 句はウィンドウ関数の結果をフィルタリングします。

QUALIFY はウィンドウ関数を使用して、 HAVING が集計関数およびGROUP BY 句を使用して実行することを実行します。

したがって、クエリの実行順序では、ウィンドウ関数が計算された後に QUALIFY が評価されます。通常、 SELECT ステートメントの句は、以下に示す順序で評価されます。

  1. FROM

  2. WHERE

  3. GROUP BY

  4. HAVING

  5. WINDOW

  6. QUALIFY

  7. DISTINCT

  8. ORDER BY

  9. LIMIT

構文

QUALIFY <predicate>

QUALIFY を使用したステートメントの一般的な形式は次のようになります(順序の一部のバリエーションは許可されますが、表示されません)

SELECT <column_list>
  FROM <data_source>
  [GROUP BY ...]
  [HAVING ...]
  QUALIFY <predicate>
  [ ... ]

パラメーター

column_list

これは通常、 SELECT ステートメントの射影句の規則に従います。

data_source

通常、データソースはテーブルですが、ビュー、 UDTF (ユーザー定義テーブル関数)など、別のテーブルのようなデータソースにすることもできます。

predicate

述語は、集計とウィンドウ関数が計算された後に結果をフィルタリングする式です。述語は HAVING 句に類似していますが、キーワード HAVING がありません。さらに、述部にはウィンドウ関数を含めることもできます。

述語の例については、このトピックの セクションをご参照ください。

使用上の注意

  • QUALIFY 句では、 SELECT ステートメントの次の句の少なくとも1つで、少なくとも1つのウィンドウ関数を指定する必要があります。

    • SELECT 列のリスト。

    • QUALIFY 句のフィルター述語。

    これらのそれぞれの例は、以下の例のセクションに示されています。

  • ウィンドウ関数を含む SELECT リスト内の式は、 SELECT リストで定義された列エイリアスによって参照できます。

  • QUALIFY は、述語で集計とサブクエリをサポートします。集計の場合、 HAVING 句と同じルールが適用されます。

  • 単語 QUALIFY は予約語です。

  • QUALIFY のSnowflake構文は ANSI 標準の一部ではありません。

QUALIFY 句は、ウィンドウ関数の結果のフィルタリングを必要とするクエリを簡素化します。QUALIFYがない場合、フィルタリングにはネストが必要です。以下の例では、 ROW_NUMBER()関数を使用して、各パーティションの最初の行のみを返します。

テーブルを作成してロードします。

CREATE TABLE qt (i INTEGER, p CHAR(1), o INTEGER);
INSERT INTO qt (i, p, o) VALUES
  (1, 'A', 1),
  (2, 'A', 2),
  (3, 'B', 1),
  (4, 'B', 2);
+-------------------------+
| number of rows inserted |
|-------------------------|
|                       4 |
+-------------------------+

このクエリは QUALIFYではなくネストを使用します。

SELECT *
  FROM (
    SELECT i, p, o, ROW_NUMBER() OVER (PARTITION BY p ORDER BY o) AS row_num
      FROM qt)
  WHERE row_num = 1;
+---+---+---+---------+
| I | P | O | ROW_NUM |
|---+---+---+---------|
| 1 | A | 1 |       1 |
| 3 | B | 1 |       1 |
+---+---+---+---------+

このクエリは QUALIFYを使用します。

SELECT i, p, o
  FROM qt
  QUALIFY ROW_NUMBER() OVER (PARTITION BY p ORDER BY o) = 1;
+---+---+---+
| I | P | O |
|---+---+---|
| 1 | A | 1 |
| 3 | B | 1 |
+---+---+---+

QUALIFY を使用して、 SELECT 列リストにあるウィンドウ関数を参照することもできます。

SELECT i, p, o, ROW_NUMBER() OVER (PARTITION BY p ORDER BY o) AS row_num
  FROM qt
  QUALIFY row_num = 1;
+---+---+---+---------+
| I | P | O | ROW_NUM |
|---+---+---+---------|
| 1 | A | 1 |       1 |
| 3 | B | 1 |       1 |
+---+---+---+---------+

前のクエリからQUALIFYを削除し、出力を比較することで、それがフィルターとしてどのように機能するかを確認できます。

SELECT i, p, o, ROW_NUMBER() OVER (PARTITION BY p ORDER BY o) AS row_num
  FROM qt;
+---+---+---+---------+
| I | P | O | ROW_NUM |
|---+---+---+---------|
| 1 | A | 1 |       1 |
| 2 | A | 2 |       2 |
| 3 | B | 1 |       1 |
| 4 | B | 2 |       2 |
+---+---+---+---------+

QUALIFY句は、集計関数や述語のサブクエリと組み合わせることもできます。このようなクエリにおいて、HAVINGはGROUPBYによる集計の後に行をフィルタリングし、一方QUALIFYはウィンドウ関数の計算後に行をフィルタリングします。クエリで両方の種類のフィルタリングが必要な場合は、両方の句を一緒に含めることができます。例:

SELECT p, SUM(o) OVER (PARTITION BY p) AS r
  FROM qt
  WHERE o < 4
  GROUP BY p, o
  HAVING SUM(i) > 3
  QUALIFY r IN (
    SELECT MIN(i)
      FROM qt
      GROUP BY p
      HAVING MIN(i) > 3);