表格中的SQL语法不正确

时间:2016-05-05 03:55:56

标签: sql-server tableau

我在Tableau中插入SQL查询时出现此错误消息。如何解决这个问题?

SQL Server当前是否不允许在子查询中使用CTE?

下面是我在

中插入查询时的Tableau输出
  

[Microsoft] [SQL Server Native Client 11.0] [SQL Server]关键字“WITH”附近的语法不正确。

     

[Microsoft] [SQL Server Native Client 11.0] [SQL Server]关键字“with”附近的语法不正确。如果此语句是公用表   表达式,xmlnamespaces子句或更改跟踪上下文   子句,前一个语句必须以分号结束。

     

[Microsoft] [SQL Server Native Client 11.0] [SQL Server]')'附近的语法不正确。

以下是我当前的CTE查询(递归)

WITH shiftHours AS (
    SELECT RowID,
    y.EMPLOYEENAME AS EMPLOYEENAME,
    -- flatten the first hour to remove the minutes and get the initial current hour
    DATEADD(hour, DATEDIFF(hour, 0, ShiftA_Start), 0) AS currentHour,
    ShiftA_Start,
    ShiftA_End,
    DATEPART(hour, ShiftA_Start) AS hourOrdinal,
    -- determine how much of the first hour is applicable. if it is minute 0 then the whole hour counts
    CAST(CASE 
        WHEN DATEADD(hour, DATEDIFF(hour, 0, ShiftA_Start), 0) = DATEADD(hour, DATEDIFF(hour, 0, ShiftA_End), 0) THEN DATEDIFF(minute, ShiftA_Start, ShiftA_End) / 60.0
        WHEN DATEPART(minute, ShiftA_Start) = 0 THEN 1.0
        ELSE (60 - DATEPART(minute, ShiftA_Start)) / 60.0
    END AS DECIMAL(5,3)) AS hourValue
FROM (
    -- use a ROW_NUMBER() to generate row IDs for the shifts to ensure each row is unique once it gets to the pivot
    SELECT ROW_NUMBER() OVER(ORDER BY ShiftA_Start, ShiftA_End) AS RowID,
    EMPLOYEENAME,
        ShiftA_Start,
        ShiftA_End
    FROM (
        -- this is where the data gets pulled from the source table and where the data types are converted from string to DATETIME
        SELECT 
        EMPLOYEENAME,
        CONVERT(DATETIME, LEFT(SHIFTA_start, 17), 103) AS ShiftA_Start,
            CONVERT(DATETIME, LEFT(SHIFTA_end, 17), 103) AS ShiftA_End
        from [TableName].[dbo].[TMS_People]
        where
        CONVERT(DATETIME, LEFT(SHIFTA_START, 17), 103) IS NOT NULL AND CONVERT(DATETIME, LEFT(SHIFTA_END, 17), 103) IS NOT NULL
        AND CONVERT(DATETIME, LEFT(SHIFTA_START, 17), 103) != CONVERT(DATETIME, LEFT(SHIFTA_END, 17), 103)


        -- this is also where you would add any filtering from the source table such as date ranges
    ) x
) AS y


UNION ALL

SELECT RowID,
EMPLOYEENAME,
    -- add an hour to the currentHour each time the recursive CTE is called
    DATEADD(hour, 1, currentHour) AS currentHour,
    ShiftA_Start,
    ShiftA_End,
    DATEPART(hour, DATEADD(hour, 1, currentHour)) AS hourOrdinal,
    CAST(CASE
        -- when this is the last time period determine the amount of the hour that is applicable
        WHEN DATEADD(hour, 2, currentHour) > ShiftA_End THEN DATEPART(minute, ShiftA_End) / 60.0
        ELSE 1
    END AS DECIMAL(5,3)) AS hourValue
from shiftHours

-- contine recursion until the next hour is after the ShiftEnd
WHERE DATEADD(hour, 1, currentHour) < ShiftA_End
)
    SELECT *
FROM (
    SELECT RowID,
EMPLOYEENAME,
    ShiftA_Start,
    ShiftA_End,
    hourValue,
    hourOrdinal
from shiftHours

    ) AS t
    PIVOT (
     SUM(hourValue)
    FOR hourOrdinal IN ([0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23])
) AS pvt
OPTION (MAXRECURSION 0);

1 个答案:

答案 0 :(得分:2)

Tableau不支持SQL Server CTE功能。

您应该尝试使用视图或子查询或存储过程/表值函数来实现相同的逻辑。

请在下面抛出线程CTE(SQL Server)不在Tableau中运行。

https://community.tableau.com/thread/105965

查看示例代码。对于CTE

如果我们有用户表(userId,userName,managerId)

CREATE VIEW vUSER AS
    WITH UserCTE AS (
    SELECT userId, userName, managerId,0 AS steps
    FROM dbo.Users
    WHERE userId = null

   UNION ALL
         SELECT mgr.userId, mgr.userName, mgr.managerId, usr.steps +1 AS        steps
     FROM UserCTE AS usr
     INNER JOIN dbo.Users AS mgr
     ON usr.managerId = mgr.userId
    )
   SELECT * FROM UserCTE ;

创建一个sp即MyProc并将所有查询放入其中   即

  CREATE procedure  dbo.MyProc AS
    WITH UserCTE AS (
    SELECT userId, userName, managerId,0 AS steps
    FROM dbo.Users
    WHERE userId = null

   UNION ALL
         SELECT mgr.userId, mgr.userName, mgr.managerId, usr.steps +1 AS        steps
     FROM UserCTE AS usr
     INNER JOIN dbo.Users AS mgr
     ON usr.managerId = mgr.userId
    )
   SELECT * FROM UserCTE ;

2使用sp_addlinkedserver创建一个链接服务器,即我告诉的是Local

3使用openquery在视图中调用sp。

     CREATE VIEW dbo.MyView
       AS(
         SELECT        *
               FROM openquery(Local,'exec mydb.dbo.MyProc'))

http://capnjosh.com/blog/how-to-call-a-stored-procedure-from-a-view-in-sql-server/