在CASE表达式的THEN中使用CTE时出现SQL错误

时间:2014-08-14 14:48:27

标签: sql sql-server common-table-expression correlated-subquery case-statement

修改

尝试将其更改为以下内容(将CTE移至顶部)。

我现在得到错误:

  

关键字' FROM'。

附近的语法不正确

我尝试在第二个' THEN'中选择一个非常简单的选择。甚至没有使用cte的条款,我得到了同样的错误。似乎不喜欢第二个中的任何子查询呢?

 WITH MainCTE AS (
      SELECT DISTINCT rownum = ROW_NUMBER() OVER (
                  ORDER BY u.PLANNED_DATE
                               )
             ,u.name
             ,u.order
             ,u.unit_code
             ,u.mode
             ,u.[SEQUENCE]
             ,u.PLANNED_DATE
             ,City = left(SUBSTRING(name, CHARINDEX(':', name) + 1, CHARINDEX(',', name)), charindex(',', SUBSTRING(name, CHARINDEX(':', name) + 2, CHARINDEX(',', name))))
             ,StateAbbrv = SUBSTRING(SUBSTRING(name, CHARINDEX(':', name) + 1, LEN(name)), CHARINDEX(',', SUBSTRING(name, CHARINDEX(':', name) + 1, LEN(name))) + 1, 4)
       FROM TableU u
       INNER JOIN TableT T ON u.ordnum = t.ordnum
       INNER JOIN TableR R ON t.CustNum = r.CustNum
   )
SELECT DISTINCT o.first_name, 
o.last_name, 
o.phone_number
,CASE t.indicator
    WHEN 2
        THEN (
                SELECT mode
                FROM TableU
                WHERE TypeInd = 'I'
                    AND [DATE] = (
                        SELECT max([DATE])
                        FROM TableU
                        WHERE TypeInd = 'I'
                        )
                )
    WHEN 3
        THEN (
                SELECT DISTINCT maincte.mode AS plannedmode
                    ,maincte.PLANNED_DATE
                    ,maincte.[SEQUENCE]
                FROM maincte
                LEFT JOIN maincte prev ON prev.rownum = maincte.rownum - 1
                LEFT JOIN maincte nex ON nex.rownum = maincte.rownum + 1
                INNER JOIN TableT T ON u.ordnum = t.ordnum
                INNER JOIN TableR R ON t.CustNum = r.CustNum
                    AND maincte.[SEQUENCE] = r.[SEQUENCE]
                    AND t.[DATE] > '01/01/2014'
                ORDER BY maincte.[LOCAL_UNIT_SEQUENCE]
                    ,maincte.PLANNED_UNIT_DATE ASC
            ) 

FROM TableR R 
INNER JOIN TableT T ON t.CustNum = r.CustNum
INNER JOIN TableO O ON t.ordNum = o.OrdNum 
WHERE t.custNum = R.custNum
        AND o.custName = R.CustName
        AND t.indicator IN (
        2
        ,3
        )
        AND r.rstatus = 'Yes' 
ORDER BY t.ordnum

下面的我的SQL语句不会运行,我很难解决它的问题。我只更改了列名和表名。

使用SQL Server 2008 Management Studio

我得到的错误是:

  

关键字' WITH'附近的语法不正确。

     

关键字'附近有'的语法不正确。如果此语句是公用表表达式或xmlnamespaces子句,则必须以分号结束前一个语句。

     

')附近的语法错误。

SQL:

SELECT DISTINCT 
    o.first_name, 
    o.last_name, 
    o.phone_number
    ,CASE t.indicator
       WHEN 2
        THEN (SELECT mode
              FROM TableU
              WHERE TypeInd = 'I'
                AND [DATE] = (SELECT max([DATE])
                              FROM TableU
                              WHERE TypeInd = 'I')
             )
       WHEN 3
        THEN (WITH MainCTE AS (
                        SELECT DISTINCT rownum = ROW_NUMBER() OVER (
                                ORDER BY u.PLANNED_DATE
                                )
                            ,u.name
                            ,u.order
                            ,u.unit_code
                            ,u.mode
                            ,u.[SEQUENCE]
                            ,u.PLANNED_DATE
                            ,City = left(SUBSTRING(name, CHARINDEX(':', name) + 1, CHARINDEX(',', name)), charindex(',', SUBSTRING(name, CHARINDEX(':', name) + 2, CHARINDEX(',', name))))
                            ,StateAbbrv = SUBSTRING(SUBSTRING(name, CHARINDEX(':', name) + 1, LEN(name)), CHARINDEX(',', SUBSTRING(name, CHARINDEX(':', name) + 1, LEN(name))) + 1, 4)
                        FROM TableU u
                        INNER JOIN TableT T ON u.ordnum = t.ordnum
                        INNER JOIN TableR R ON t.CustNum = r.CustNum
                        )
                SELECT DISTINCT maincte.mode AS plannedmode
                    ,maincte.PLANNED_DATE
                    ,maincte.[SEQUENCE]
                FROM maincte
                LEFT JOIN maincte prev ON prev.rownum = maincte.rownum - 1
                LEFT JOIN maincte nex ON nex.rownum = maincte.rownum + 1
                INNER JOIN TableT T ON u.ordnum = t.ordnum
                INNER JOIN TableR R ON t.CustNum = r.CustNum
                    AND maincte.[SEQUENCE] = r.[SEQUENCE]
                    AND t.[DATE] > '01/01/2014'
                ORDER BY maincte.[LOCAL_UNIT_SEQUENCE]
                    ,maincte.PLANNED_UNIT_DATE ASC
            ) 
FROM 
   TableR R 
INNER JOIN 
   TableT T ON t.CustNum = r.CustNum
INNER JOIN 
   TableO O ON t.ordNum = o.OrdNum 
WHERE 
   t.custNum = R.custNum
   AND o.custName = R.CustName
   AND t.indicator IN (2, 3)
   AND r.rstatus = 'Yes' 
ORDER BY 
   t.ordnum

3 个答案:

答案 0 :(得分:2)

您不能在子查询中使用CTE,但是如果您在初始查询之前移动CTE,则应该能够在子查询中访问它。

编辑完成后,我再查看了一下您的查询,并发现了以下问题:

1)你在案件陈述结束时错过了END 2)可以从case语句中的子查询中获取多行 3)您的第二个子查询正在尝试返回3列

答案 1 :(得分:0)

正如pyrrosa所说,你无法在子查询中声明CTE。您必须在声明的开头声明它。

WITH语句要求先前的语句以分号结束。这就是为什么你经常会在WITH语句之前看到分号,如下所示:

;WITH MainCTE AS...

我希望这会解决错误:

  

关键字'附近有'的语法不正确。如果这个陈述是   公用表表达式或xmlnamespaces子句,前一个   声明必须以分号结束。

添加分号后可能会出现不同的错误。 CASE语句中的子查询不能返回多行;它们必须返回单个标量值。查询CTE的THEN语句应返回单个标量值,该值以某种方式与当前行的值相关。目前,它可以返回多个值。

您的查询给我错误:

  

Msg 1033,Level 15,State 1,Line 46

     

ORDER BY子句在视图,内联函数,派生表,子查询和公用表表达式中无效,除非还指定了TOP或FOR XML。

这是因为您在ORDER BY子句中不能拥有THEN,因为它只能返回单个标量值。

此外,您不能在一个案例中返回多个列,而在另一个案例中返回一个列。如果您尝试返回多个列,则会出现此错误(在SQL Server 2008 R2上):

  

Msg 116,Level 16,State 1,Line 6

     

当EXISTS没有引入子查询时,只能在选择列表中指定一个表达式。

您可能需要UNION个2个不同的查询 - 但UNION必须返回相同数量的列。如果这对您不起作用,也许您可​​以使用单独的查询来返回不同的表。

答案 2 :(得分:0)

我发现您的热门查询存在两个问题。

  1. 您错过了案例陈述中的END。这就是你得到Incorrect syntax near the keyword 'FROM'.错误的原因。

  2. 您的子查询中无法获得订单。