函 ANY_VALUE 式會回傳一組列中任意(若可能)值NULL 。 你可以同時用作聚合函數和視窗(解析)函數:
- 總體使用量:從整個群組中回傳任意值。
- 視窗使用:在定義的視窗框架上運作,並從整個視窗中回傳任意值。
語法
聚合函數語法:
ANY_VALUE ( [ ALL | DISTINCT ] expression )
解析函數語法:
ANY_VALUE ( [ ALL | DISTINCT ] expression) OVER ( [ <partition_by_clause> ] [ <order_by_clause> ] )
引數
ALL
將彙總函式套用至所有值。 ALL 是預設且唯一有意義的選項,且僅支援 ISO 相容性。
獨特的
DISTINCT 與 沒有 ANY_VALUE意義,並且僅適用於 ISO 相容性。
表達式
要傳回的值。 任何值都可以作為結果回傳,但如果可能,會跳過這些 NULL 值。
OVER 條款
partition_by_clause將子句產生FROM的結果集劃分為多個區塊,並對每個區塊套用函數。
如果你沒有指定這個子句,函式會把查詢結果集的所有列都當作一個群組來處理。
在套用函式之前,order_by_clause 可指定資料順序。 如果你指定 partition_by_clause,它會決定分割區中資料的順序。 order_by_clause不是必須的。
欲了解更多資訊,請參閱 SELECT - OVER 條款(Transact-SQL)。
傳回類型
回傳與 expression 類型相同的值。
備註
ANY_VALUE 不具決定性。 如需詳細資訊,請參閱確定性與非確定性函式。 與 或 LAST_VALUE不同FIRST_VALUE,ANY_VALUE並不提供確定性的排序。 它設計給查詢邏輯不重要的精確值。
該函數嘗試在可能時回傳非值NULL,且僅當所有值皆為 NULL時回傳NULL值。
應用案例
一個常見的使用情境 ANY_VALUE 是需要在依照鍵欄位分組的結果集中包含非鍵欄位。 例如,如果你將列分組為 StoreID,可以用 ANY_VALUE 來回傳欄位的值,例如商店名稱、地址或其他描述性屬性,而不必將它們加入 GROUP BY 子句,也不需要使用較昂貴的函式如 MAX、 MIN、 FIRST_VALUE、 ,或 LAST_VALUE 將它們納入投影中。 此方法簡化查詢設計、提升可讀性,並提升效能,因為 SQL 查詢無需對描述欄位進行不必要的分組。 因此,你的彙整會保持簡潔、易於維護且更有效率。
Examples
答: 取得任何非 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. 專案描述欄
此查詢透過與 DimStore、 、 分組StoreKey,並利用 取得關鍵門市資訊ANY_VALUE,來總結每家門市的總銷售額FactSales。
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函數,你可以包含非分組欄位(如 StoreName、 StoreDescription、 ZipCodeStoreStatusStoreFaxAddressLine1StorePhoneAddressLine2,且不在子GROUP BY句中列出)。
C. 將列的值解開到欄
FactSales表格中每個行項目包含一列,其中 OrderKey 表示順序。 對於每個順序,屬性 OrderDate如 、 DeliveryDate、 CustomerKey、 StoreKey 會在所有屬於相同 OrderKey列的列中重複出現。 相較之下,依 ProductKey 項目而異,每個 LineNumber項目有一個產品。
以下查詢會將這些列進行 FactSales 樞軸化,使每列 OrderKey 成為單一列。 它保留共享的訂單層級屬性,並為每個行號所關聯的產品建立獨立欄位(ProductKey0, , ProductKey1...)。 該 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 數,可以避免將 OrderDate、 DeliveryDate、 CustomerKey、 StoreKey 置於 GROUP BY 子句中。 此ANY_VALUE函式簡化查詢流程,且能提升效能,因為子GROUP BY句中僅使用單一欄位(OrderKey)。
該 ANY_VALUE + CASE WHEN 模式會針對每個行項目擷取適當的 ProductKey 資料,並將它們作為獨立欄位回傳。 實務上,此模式產生產品鍵的程式化樞軸(作為傳統 UNPIVOT 運算子的替代方案)。
D. 每兩欄劃分的隨機值
你正在製作一份銷售層級的詳細報告,並每日為每家門市提供關鍵績效指標(KPI)。 在報告中,你需要回傳相同的 SalesOrderNumber 每個(StoreKey, DateKey) 分割,若沒有商業規則,則選擇特定的 SalesOrderNumber。 報告中不需要選擇每行最早、最新或最大訂單。 例如,使用者介面會在每行旁顯示「店鋪日的參考訂單」,讓分析師能快速跳轉到(店鋪、日)對的訂單。
目標是每家店(店鋪、一天)退一個固定 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;
如果你用欄位參考取代表達fs.SalesOrderNumber式ANY_VALUE(fs.SalesOrderNumber),標籤會逐列變化;你就會失去「每(商店、一天)一個一致標籤」的行為。