ナレッジベース

共通テーブル式の使用


発行: 20 Dec 2016
最終修正日: 20 Jul 2023

ご質問

Tableau で共通テーブル式 (CTE) を使用する方法。
 

環境

  • Tableau Desktop
  • SQL Server
  • Teradata
  • IBM DB2

回答

  1. [データ] > [新しいデータソース] を選択し、必要なデータ ソースを選択します。
  2. [サーバー接続] ダイアログ ボックスで [初期 SQL] を選択します。
  3. [初期 SQL] フィールドに CTE を入力します。
    次の例では、"Employees (従業員)" 表で再帰的な自己結合を使用することにより、OrganizationChart という名前の共通テーブル式を使用して従業員の報告階層構造を構築します。構文はデータソースによって若干異なります。 

    SQL Server の場合、クエリの最後で SELECT を使用するのではなく、SELECT INTO [一時テーブル名] を使用してローカル一時テーブルを作成します。 
    WITH OrganizationChart (Id, [Name],  [Level], ManagerID) AS (
    SELECT
    Id, [Name], 0 as [Level], ManagerID
    FROM
    [dbo].[Employees] emp
    WHERE
    ManagerID IS NULL
    UNION ALL
    SELECT
    emp.ID, emp.[Name], [Level] + 1, emp.ManagerID
    FROM [dbo].[Employees] emp
    INNER JOIN OrganizationChart d ON
    emp.ManagerID = d.Id
    )
    SELECT  [Id], [Name], [Level], [ManagerID] INTO #ctedemo from OrganizationChart


    Teradata の場合、CREATE VOLATILE TABLE [一時テーブル名] を使用して一時テーブルを作成します。 
    CREATE VOLATILE TABLE ctedemo AS (WITH RECURSIVE OrganizationChart (Id, Name,  Level, ManagerID) AS (
    SELECT
    Id, Name, 0 as Level, ManagerID
    FROM
    TEST.Employees emp
    WHERE
    ManagerID IS NULL
    UNION ALL
    SELECT
    emp.ID, emp.Name, Level + 1, emp.ManagerID
    FROM TEST.Employees emp
    INNER JOIN OrganizationChart d ON
    emp.ManagerID = d.Id
    ) SELECT  Id, Name, Level, ManagerID from OrganizationChart) WITH DATA NO PRIMARY INDEX
    ON COMMIT PRESERVE ROWS


    IBM DB2 の場合:
    DECLARE GLOBAL TEMPORARY TABLE SESSION.ctedemo(ID int, Name varchar(50), Level int, ManagerID int) on commit preserve rows with replace not logged;
    INSERT INTO SESSION.ctedemo(ID, Name, Level, ManagerID) WITH OrganizationChart (Id, Name,  Level, ManagerID) AS (
    SELECT
    Id, Name, 0 as Level, ManagerID
    FROM
    Employees emp
    WHERE
    ManagerID IS NULL
    UNION ALL
    SELECT
    emp.ID, emp.Name, Level + 1, emp.ManagerID
    FROM Employees emp, OrganizationChart d
    where
    emp.ManagerID = d.Id
    )
    SELECT  Id, Name, Level, ManagerID from OrganizationChart

     
  4. レコードを挿入した一時テーブルから選択するカスタム SQL クエリを作成します。 
    たとえば、SQL Server では次のようになります。 
    SELECT * from #ctedemo
    Teradata では次のようになります。 
    SELECT * from ctedemo
    IBM DB2 では次のようになります。 
    SELECT * FROM SESSION.ctedemo
     
従業員が挿入された表は次のようになります。

ID

Name

ManagerID

1

John

NULL

2

Jim

1

3

Jane

1

4

Tom

3

5

Bob

4

6

Rob

3

7

Mike

1

上記の解決策により、次のような結果が返されます。 

ID

Name

Level

ManagerID

1

John

0

NULL

2

Jim

1

1

3

Jane

1

1

7

Mike

1

1

4

Tom

2

3

6

Rob

2

3

5

Bob

3

4

詳細情報

Tableau がデータソースにクエリを実行すると、次のようなクエリでカスタム SQL が渡されます。

SELECT TOP 1 * from ( [All your Custom SQL here] ) as [TableauSQL]
SQL Server と Teradata はサブクエリ内での CTE の使用をサポートしないため、結果がエラーになります。
初期 SQL はサブクエリ内でパスされないため、CTE で使用することができます。

この機能を今後の製品リリースに組み込むことに賛成する方は、次の Community Idea に投票してください。
CTE compatibility with SQL Server (v. 10.0)
この記事で問題は解決しましたか?