カテゴリ:

クエリ構文

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>
  [ ... ]
列リスト

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

データソース

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

述語

述語は、集計とウィンドウ関数が計算された後に結果をフィルタリングする式です。述語は 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);

このクエリは 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 を削除し、出力を比較することで、 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 句は集計と組み合わせることもでき、述語にサブクエリを含めることができます。例:

SELECT c2, SUM(c3) OVER (PARTITION BY c2) as r
  FROM t1
  WHERE c3 < 4
  GROUP BY c2, c3
  HAVING SUM(c1) > 3
  QUALIFY r IN (
    SELECT MIN(c1)
      FROM test
      GROUP BY c2
      HAVING MIN(c1) > 3);