次の方法で共有


ANY_VALUE (Transact-SQL)

適用対象:Microsoft Fabric のウェアハウス

ANY_VALUE関数は、行のグループから任意の (可能な場合はNULLではない) 値を返します。 集計関数とウィンドウ (分析) 関数の両方として使用できます。

  • 集計使用法: グループ全体から任意の値を返します。
  • ウィンドウの使用法: 定義されたウィンドウ フレームを操作し、ウィンドウ全体から任意の値を返します。

Transact-SQL 構文表記規則

構文

集計関数の構文:

ANY_VALUE ( [ ALL | DISTINCT ] expression )

分析関数の構文:

ANY_VALUE ( [ ALL | DISTINCT ] expression) OVER ( [ <partition_by_clause> ] [ <order_by_clause> ] )

引数

全て

すべての値にこの集計関数を適用します。 ALL は既定の意味のあるオプションであり、ISO 互換性でのみ使用できます。

独特

DISTINCTANY_VALUEでは意味を持たず、ISO 互換でのみ使用できます。

expression

返される値。 結果として任意の値を返すことができますが、可能な場合、 NULL 値はスキップされます。

OVER 句

partition_by_clauseでは、FROM句によって生成された結果セットがパーティションに分割され、関数が各パーティションに適用されます。

この句を指定しない場合、関数はクエリ結果セットのすべての行を 1 つのグループとして扱います。

order_by_clause は、関数を適用する前にデータの順序を決定します。 partition_by_clauseを指定すると、パーティション内のデータの順序が決まります。 order_by_clauseは必要ありません。

詳細については、「 SELECT - OVER 句 (Transact-SQL)」を参照してください。

戻り値の型

式と同じ型の値を返 します

注釈

ANY_VALUE は非決定的です。 詳細については、「 決定論的関数と非決定的関数」を参照してください。 FIRST_VALUELAST_VALUEとは異なり、ANY_VALUEは決定論的な順序付けを提供しません。 これは、正確な値がクエリ ロジックにとって重要でない場合に向けて設計されています。

この関数は、可能な場合はNULL以外の値を返そうとし、すべての値がNULL場合にのみNULL値を返します。

利用シーン

ANY_VALUEの一般的なユース ケースは、キー列でグループ化された結果セットにキー以外の列を含める必要がある場合です。 たとえば、 StoreIDで行をグループ化する場合は、 ANY_VALUE を使用して、 GROUP BY 句に追加したり、 MAXMINFIRST_VALUELAST_VALUE などのより高価な関数を使用したりせずに、ストア名、住所、その他の記述属性などの列の値を返して、それらをプロジェクションに含めることができます。 この方法では、SQL クエリで説明列に対して不要なグループ化を実行する必要がないため、クエリの設計が簡略化され、読みやすさが向上し、パフォーマンスが向上します。 その結果、集計は簡潔で、保守が容易になり、効率が向上します。

例示

A. NULL 以外の値を取得する

この単純なクエリは、 ANY_VALUE が一連の値から任意の NULL 以外の値を返す方法を示しています。

SELECT ANY_VALUE(v)
FROM (VALUES (NULL), (NULL), (NULL), (NULL), (2), (NULL), (NULL), (7), (NULL), (NULL)) AS t(v);

この関数は NULL 値を無視し、非決定的な方法でNULL 以外の値 (2、場合によっては 7) のいずれかを返します。

B. プロジェクトの説明列

このクエリでは、 FactSalesDimStoreに結合し、 StoreKeyでグループ化し、 ANY_VALUEを使用してキー ストアの詳細を取得することで、ストアあたりの売上の合計を集計します。

USE ContosoDW;  
GO  
SELECT
    fs.StoreKey,
    ANY_VALUE(ds.StoreName)        AS StoreName,
    ANY_VALUE(ds.StoreDescription) AS StoreDescription,
    ANY_VALUE(ds.Status)           AS StoreStatus,
    ANY_VALUE(ds.Phone)            AS StorePhone,
    ANY_VALUE(ds.Fax)              AS StoreFax,
    ANY_VALUE(ds.ZipCode)          AS ZipCode,
    ANY_VALUE(ds.AddressLine1)     AS AddressLine1,
    ANY_VALUE(ds.AddressLine2)     AS AddressLine2,
    SUM(fs.UnitPrice * fs.SalesQuantity) AS SalesAmount
FROM dbo.FactSales AS fs
LEFT JOIN dbo.DimStore AS ds
    ON ds.StoreKey = fs.StoreKey
GROUP BY
    fs.StoreKey;  

ANY_VALUE関数を適用すると、グループ化されていない列 (StoreNameStoreDescriptionStoreStatusStorePhoneStoreFaxZipCodeAddressLine1AddressLine2など) をGROUP BY句に一覧表示せずに含めることができます。

C. 行から列への値のピボット解除

FactSales テーブルには、行項目ごとに 1 行が含まれています。ここで、OrderKeyは注文を識別します。 順序ごとに、 OrderDateDeliveryDateCustomerKeyStoreKey などの属性が、同じ OrderKeyに属するすべての行で繰り返されます。 一方、 ProductKey は品目によって異なり、 LineNumberごとに 1 つの製品があります。

次のクエリでは、各OrderKeyが 1 つの行になるように、FactSales行をピボットします。 共有注文レベルの属性を保持し、各行番号に関連付けられている製品の個別の列 (ProductKey0ProductKey1、...) を作成します。 ANY_VALUE関数は、各グループから代表的な値を選択するために使用され、条件式は特定の品目ごとに製品を抽出します。

SELECT
    OrderKey,
    -- Projecting groups that are same within the group.
    ANY_VALUE(OrderDate)      AS OrderDate,
    ANY_VALUE(DeliveryDate)   AS DeliveryDate,
    ANY_VALUE(CustomerKey)    AS CustomerKey,
    ANY_VALUE(StoreKey)       AS StoreKey,
    -- Unpivoted values returned as multiple columns per row
    ANY_VALUE(IIF(LineNumber = 0, ProductKey, NULL)) AS ProductKey0,
    ANY_VALUE(IIF(LineNumber = 1, ProductKey, NULL)) AS ProductKey1,
    ANY_VALUE(IIF(LineNumber = 2, ProductKey, NULL)) AS ProductKey2,
    ANY_VALUE(IIF(LineNumber = 3, ProductKey, NULL)) AS ProductKey3,
    ANY_VALUE(IIF(LineNumber = 4, ProductKey, NULL)) AS ProductKey4,
    ANY_VALUE(IIF(LineNumber = 5, ProductKey, NULL)) AS ProductKey5,
    ANY_VALUE(IIF(LineNumber = 6, ProductKey, NULL)) AS ProductKey6
FROM dbo.FactSales
GROUP BY
    OrderKey;

ANY_VALUE関数を使用すると、GROUP BY句にOrderDateDeliveryDateCustomerKey、およびStoreKeyを配置しないようにします。 ANY_VALUE関数はクエリを簡略化し、GROUP BY句で 1 つの列 (OrderKey) のみが使用されるため、パフォーマンスを向上させることができます。 ANY_VALUE + CASE WHEN パターンは、各行項目の適切なProductKeyを抽出し、それらを個別の列として返します。 実際には、このパターンでは、プロダクト キーのプログラムによるピボットが生成されます (従来の UNPIVOT 演算子の代替手段)。

D. 2 列パーティションあたりのランダム値

店舗ごとに日次主要業績評価指標 (KPI) を含む販売レベルの詳細レポートを作成しています。 レポートでは、特定のSalesOrderNumberを選択するビジネス ルールが存在しない (StoreKeyDateKey) パーティションごとに同じSalesOrderNumberを返す必要があります。 レポート内の行ごとに最も早い、最新、または最大の順序を選択する必要はありません。 たとえば、ユーザー インターフェイスでは各行の横に "店舗日の参照注文" が表示されるため、アナリストは (店舗、日) ペアから注文にすばやくジャンプできます。

意図は、(ストア、日) ごとに 1 つの一貫した SalesOrderNumber を返します。

USE ContosoDW;
GO
SELECT
    fs.DateKey,
    fs.StoreKey,

    -- Window KPI: total sales per Store-Day (keeps row-level output)
    SUM(fs.UnitPrice * fs.SalesQuantity)
      OVER (PARTITION BY fs.StoreKey, dd.DateKey) AS DailySales,

    -- Partition label with no preferred ordering: any one order from that Store-Day
    ANY_VALUE(fs.SalesOrderNumber)
      OVER (PARTITION BY fs.StoreKey, dd.DateKey) AS SampleOrderNumber

FROM dbo.FactSales AS fs;

ANY_VALUE(fs.SalesOrderNumber)式をfs.SalesOrderNumber列参照に置き換えた場合、ラベルは行ごとに異なります。"1 つの一貫性のあるラベル (ストア、日)" の動作は失われます。