メインコンテンツへスキップ
テーブル値関数のサポートは、ドライバーの試験的な機能です。この機能は、SQL-92 準拠というドライバーのコア範囲を超えるものです。そのため、これらの関数のパフォーマンスは最適ではない場合があります。

テーブル値関数の句

CROSS APPLY

CROSS APPLY 演算子は、先行するテーブル式によって生成されたテーブルまたは結果セットの各行に対してサブクエリを実行するために使用されます。 構文
<table_expression_1> CROSS APPLY <table_expression_2>
2 番目のテーブル式は、最初のテーブル式の結果を参照して、派生カラムを作成したり、テーブル値関数を介して変更されたレコードセットを作成したりすることができます。 結果として得られる各レコードは、分割されたレコードのインスタンスであり、関数によって分割された値を含むカラムを除き、すべてのカラム値が同じになります。

WITH

WITH 句は、特定のテーブル値関数と組み合わせて使用され、分割される構造内の構成要素(キー、要素名、属性名など)に対してマッチングを行ったり、関数から生成されるカラムのメタデータを指定するために使用されます。
SELECT A.ColumnName, X.DerivedColumnName FROM TableName A CROSS APPLY <table-valued function> WITH (DerivedColumnName varchar(255)) AS X

テーブル値関数

STRING_SPLIT

先行するテーブル式のレコードセット内の各レコードに対して、区切り文字(input_text)を含むカラムを区切り文字で分割して部分文字列に分け、部分文字列ごとに 1 つのレコードを返します。 構文
STRING_SPLIT(input_text,delimiter)
パラメータ
  • input_text パースしたい値を含むカラム。
  • delimiter input_text で指定されたカラムの値を分割するために使用する文字。
「SplitColumn」という名前のカラムに、次のような内容があるとします。
One-Two-Three
この値を複数のレコードに展開するには:
SELECT A.ID, X.Value FROM [TableWithDelimitedStringField] A CROSS APPLY STRING_SPLIT(A.SplitColumn,'-') WITH (Value VARCHAR(255)) AS X
 
-- Results:
-----------
|ID|Value|
|1|One|
|1|Two|
|1|Three|

JSONTABLE

先行するテーブル式のレコードセット内の各レコードに対して、JSON 配列(json_content)内のキーのうち、WITH 句で指定されたキーと一致するもののインスタンスごとに、「jsonpath」入力で指定されたスコープで 1 つのレコードを返します。 構文
JSONTABLE(json_content,[jsonpath])
パラメータ
  • json_content JSON の「テーブル」(オブジェクトの配列)。内容はネストできますが、ルートレベルでは他の JSON 構造ではなく、単一の JSON 配列でなければなりません。WITH 句で指定されたキーのすべてのインスタンスの値は、ルートレベルの JSON 配列の直接の子要素となるサブ構造についてのみ取得できます。
  • jsonpath json_content 配列内で、内容を取得したいスコープを定義するオプションの JSONPath クエリ。WITH 句で指定された JSON キーは、このパラメータで定義されたスコープに存在している必要があります。デフォルトは JSON ルート($)です。ID カラムと「JSONColumn」という JSON 内容を持つカラムを含む、単一のレコードを持つサンプルテーブルを考えてみましょう。内容は次のとおりです。
[
    {
        "name": "Samuel",
        "email": "sam@gmail.com",
        "extrainfo": {
            "city": "Seattle"
        }
    },
    {
        "name": "Katherine",
        "email": "kat@gmail.com",
    },
    {
        "name": "George",
        "email": "george23@gmail.com",
    },
    {
        "name": "Carlos",
        "email": "carlos32@gmail.com",
    }
]
特定のキーのすべての値を抽出するには、JSONTABLE 関数でスコープを指定し、WITH 句で目的のキーを指定します。
SELECT A.ID, X.name FROM [TableWithJSONField] A CROSS APPLY JSONTABLE(A.JSONColumn) WITH (name VARCHAR(255)) AS X
 
-- Results:
|ID|name|
---------
|1 |Samuel|
|1 |Katherine|
|1 |George|
|1 |Carlos|

XMLTABLE

先行するテーブル式の結果セット内の各レコードに対して、XML 構造(xml_content)内の要素や属性のうち、WITH 句で指定されたタグ名や属性名と一致するもののそれぞれについて、「xpath」入力で指定されたスコープで 1 つのレコードを返します。 構文
XMLTABLE(xml_content,[xpath,child_type])
パラメータ
  • xml_content XML 構造を含むカラム。
  • xpath WITH 句で指定されたタグ名や属性名と一致する内容をドライバーが抽出する、XML 構造内のスコープを指定するオプションの XPath。サブ要素の内容を抽出する場合、ドライバーはルートレベル(深さ 0)のタグ、ルートの直接の子(深さ 1)、およびそれらの子の子(深さ 2)からすべての内容を取得できます。要素の属性内容を抽出する場合、ドライバーはルートレベル(深さ 0)の指定された属性を含むタグ、およびルートレベル要素の直接の子(深さ 1)からすべての内容を取得できます。
  • child_type WITH 句で指定されたカラムが内容を識別するためにチェックされる親要素(xpath 入力で指定)の部分を指定するオプションのパラメータ。次の値を指定できます:
    • 0:WITH 句のカラムは、親要素の属性名およびサブ要素のタグ名との一致についてチェックされます。
    • 1:WITH 句のカラムは、親要素の属性名との一致についてチェックされます。
    • 2:WITH 句のカラムは、親要素のサブ要素のタグ名との一致についてチェックされます。指定しない場合、デフォルトは 0 です。
ID カラムと「XMLContent」という XML 内容を持つカラムを含む、単一のレコードを持つサンプルテーブルを考えてみましょう。内容は次のとおりです。
<shoppingList>
    <item>
        <name>Apples</name>
        <quantity>3</quantity>
        <unit>Kg</unit>
    </item>
    <item>
        <name>Bread</name>
        <quantity>2</quantity>
        <unit>Loaf</unit>
        <extrainfo>
            <Type>Whole-Grain</Type>
        </extrainfo>
    </item>
    <item>
        <name>Milk</name>
        <quantity>1</quantity>
        <unit>Carton</unit>
    </item>
    <item>
        <name>Eggs</name>
        <quantity>12</quantity>
        <unit></unit>
    </item>
</shoppingList>
サブ要素の内容を抽出するには、XMLTABLE 関数でスコープを指定し、WITH 句で目的の要素名を指定します。XMLTABLE 関数の child_type 入力が 1 に設定されている場合、これは動作しないことに注意してください。
SELECT A.ID, X.name FROM [TableWithXMLField] A CROSS APPLY XMLTABLE(A.XMLContent,'//*/item') WITH (name VARCHAR(255)) AS X
 
-- Results:
|ID|name|
---------
|1|Apples|
|1|Bread|
|1|Milk|
|1|Eggs|
ID カラムと「XMLContent」という XML 内容を持つカラムを含む、単一のレコードを持つサンプルテーブルを考えてみましょう。内容は次のとおりです。
<restaurant>
  <dish type="appetizer">
    <name lang="en">Caprese Salad</name>
    <chef>Chef Giovanni</chef>
    <price currency="USD">9.99</price>
  </dish>
  <dish type="main-course">
    <name lang="fr">Boeuf Bourguignon</name>
    <chef>Chef Marie</chef>
    <price currency="EUR">19.99</price>
  </dish>
  <dish type="dessert">
    <name lang="es">Tres Leches Cake</name>
    <chef>Chef Alejandro</chef>
    <price currency="MXN">89.99</price>
  </dish>
</restaurant>
属性内容を抽出するには、XMLTABLE 関数でスコープを指定し、WITH 句で目的の属性名を指定します。XMLTABLE 関数の child_type 入力が 2 に設定されている場合、これは動作しないことに注意してください。
SELECT A.ID, X.type FROM [TableWithXMLField] A CROSS APPLY XMLTABLE(A.XMLContent,'//*/dish') WITH (type VARCHAR(255)) AS X
 
-- Results:
|ID|type|
---------
|1|appetizer|
|1|main-course|
|1|dessert|

CSVTABLE

先行するテーブル式の結果セット内の各レコードに対して、CSV テーブル(csv_content)を含むカラムから読み取り、その CSV テーブル内の各レコードに対して、WITH 句で指定された CSV カラムの値を含む 1 つのレコードを返します。 構文
CSVTABLE(csv_content,[delimiter])
パラメータ
  • csv_content CSV テーブルを含むカラム。
  • delimiter csv_content 入力に含まれる CSV 内容を分割する、オプションのカスタム区切り文字(カンマの代わり)。
ID カラムと「CSVContent」という CSV テーブルを含むカラムを含む、単一のレコードを持つサンプルテーブルを考えてみましょう。内容は次のとおりです。
Name;Category;Price
Apple;Fruit;0.99
Spaghetti;Pasta;5.49
Chicken Breast;Meat;8.99
Broccoli;Vegetable;2.49
「Name」カラムのすべての値を選択し、カスタム区切り文字(;)に対応するには:
SELECT A.ID, X.Name FROM [TableWithCSVField] A CROSS APPLY CSVTABLE(A.CSVContent,';') WITH (Name VARCHAR(255)) AS X
 
-- Results:
|ID|Name|
-----------
|1|Apple|
|1|Spaghetti|
|1|Chicken Breast|
|1|Broccoli|