【问题标题】:SQL Error when using CTE inside THEN of CASE expression在 CASE 表达式的 THEN 中使用 CTE 时出现 SQL 错误
【发布时间】:2014-08-14 14:48:27
【问题描述】:

编辑:

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

我现在得到错误:

关键字“FROM”附近的语法不正确。

我尝试在甚至没有使用 cte 的第二个“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 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”附近的语法不正确。

关键字“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

【问题讨论】:

  • with 语句位于主 select 之前。这是 SQL Server 中 CTE 的语法。但是您的查询有多个问题。例如,看起来子查询将在需要标量子查询的上下文中返回多行和多列。
  • 您的 with 子句带来了多个列,这对于您的语句中的 case (then) 运算符无效。它应该在 select 语句中只带一列,只返回一行。
  • 不应该先运行where子句吗?这会将其缩小到选择将使用的一行值
  • 即使我选择了top 1,也没有办法在THEN子句中加入CTE?
  • 您经常会看到;WITH,其中出现了前导分号,以保证之前的任何语句都已终止。

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


【解决方案1】:

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

在您编辑后,我又查看了您的查询,发现以下问题:

1) 您在案例陈述的末尾缺少 END 2)可以从您的案例语句中的子查询中取回多行 3)您的第二个子查询试图返回 3 列

【讨论】:

  • 我试过这个,然后在第二个之后有一个正常的选择,现在是这样:
  • 有什么方法可以提供示例数据和给定示例数据的示例输出?
【解决方案2】:

正如 pyrrosa 所说,您不能在子查询中声明 CTE。您必须在语句的开头声明它。

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

;WITH MainCTE AS...

我希望这将解决错误:

关键字“with”附近的语法不正确。如果这个语句是 公共表表达式或 xmlnamespaces 子句,前一个 语句必须以分号结束。

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

您的查询给了我错误:

消息 1033,级别 15,状态 1,第 46 行

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

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

此外,您不能在一种情况下返回多列而在另一种情况下返回单列。如果您尝试返回多个列,您将收到此错误(在 SQL Server 2008 R2 上):

消息 116,级别 16,状态 1,第 6 行

当不使用 EXISTS 引入子查询时,选择列表中只能指定一个表达式。

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

【讨论】:

    【解决方案3】:

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

    1. 您的案例陈述中缺少END。这就是您收到 Incorrect syntax near the keyword 'FROM'. 错误的原因。

    2. 您的子查询中不能有 order by。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多