知识库

使用通用表表达式


发布时间: 20 Dec 2016
上次修改日期: 20 Jul 2023

问题

如何在 Tableau 中使用通用表表达式 (CTE)。
 

环境

  • Tableau Desktop
  • SQL Server
  • Teradata
  • IBM DB2

答案

  1. 选择“数据”>“新建数据源”,并选择所需的数据源。
  2. 在“服务器连接”对话框中,单击“初始 SQL”
  3. 在“初始 SQL”字段中输入您的 CTE。
    下面的示例使用“员工”表上的递归自联接用名为 OrganizationChart 的通用表表达式构建员工报告层次结构。语法根据数据源略有不同。 

    对于 SQL Server,我们将通过在查询的结尾使用“SELECT INTO [临时表名称]”(而不是 "SELECT")来创建一个本地临时表: 
    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 [Temp Table Name] 创建了一个临时表: 
    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

名称

ManagerID

1

John

NULL

2

Jim

1

3

Jane

1

4

Tom

3

5

Bob

4

6

Rob

3

7

Mike

1

以上解决方案将返回如下结果: 

ID

名称

级别

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。

为了表达您对在将来的产品版本中包括此功能的支持,请为以下社区理念投下您的一票:
CTE 与 SQL Server 的兼容性 (v.10.0)
此文章是否已解决问题?