SQL 中的 PIVOT 给出错误 - ORA-00933: SQL 命令未正确结束

Posted

技术标签:

【中文标题】SQL 中的 PIVOT 给出错误 - ORA-00933: SQL 命令未正确结束【英文标题】:PIVOT in SQL gives error - ORA-00933: SQL command not properly ended 【发布时间】:2020-08-16 11:20:45 【问题描述】:

Oracle SQL 中的以下查询为我提供了一个由 ID、Key、Value 组成的表。我想将键转换为列,将值转换为列值,同时保持 ID 作为行的 ID。我尝试了 PIVOT 查询。但我收到一个错误 - ORA-00933: SQL 命令未正确结束。

初始 SQL

SELECT * FROM API.publisher_message_queue_detail
WHERE message_seq_id 
IN (SELECT message_seq_id FROM API.publisher_message_queue WHERE status='N' AND MESSAGE_TYPE='RetailerNewConnection') ;

结果表

我想将此表转换为

我尝试过的 PIVOT 查询

SELECT * FROM API.publisher_message_queue_detail
WHERE message_seq_id IN 
    (SELECT message_seq_id FROM API.publisher_message_queue WHERE status='N' AND MESSAGE_TYPE='RetailerNewConnection') 
    PIVOT(
    COUNT(message_seq_id)
    FOR MSG_KEY
    IN (
        'MobileNo',
        'ActivatedDate',
        'ActSimNo',
        'ActActdevice',
        'PmsProfileID',
        'PaymentMode',
        'AgentCode',
        'ActPrePost',
        'Sbu',
        'Channel',
        'SalesPath',
        'OrderId'
    )
  )
;

但是,我收到以下错误。我的错误是什么?

ORA-00933: SQL command not properly ended
00933. 00000 -  "SQL command not properly ended"
*Cause:    
*Action:
Error at Line: 10 Column: 5

【问题讨论】:

你可以粘贴数据而不是图像。 你不应该使用 * 但只有你想要的列和任何不属于 PIVOT 的列将被分组并显示为一行。 如果您选择的是计数,您希望如何生成所需输出列中的“值”?暂时不管你的问题的其他一切,想想这个简单的问题。 【参考方案1】:

我不喜欢将发明的语法用于没有它很容易编写的东西。只需使用条件聚合:

SELECT mq.AgentCode, . . . ,  -- whatever columns define each row
       MAX(CASE WHEN mqd.msg_key = 'MobileNo' THEN mqd.msg_value END) as MobileNo,
       MAX(CASE WHEN mqd.msg_key = 'ActivatedDate' THEN mqd.msg_value END) as ActivatedDate,
       . . . 
FROM API.publisher_message_queue JOIN
     API.publisher_message_queue_detail mqd
     ON mqd.message_seq_id = mq.message_seq_id
WHERE mq.status = 'N' AND mq.MESSAGE_TYPE = 'RetailerNewConnection'
GROUP BY mq.AgentCode, . . . ;

或者如果你想要父表中的所有列:

SELECT *
FROM API.publisher_message_queue JOIN
     (SELECT mqd.message_seq_id,
             MAX(CASE WHEN mqd.msg_key = 'MobileNo' THEN mqd.msg_value END) as MobileNo,
             MAX(CASE WHEN mqd.msg_key = 'ActivatedDate' THEN mqd.msg_value END) as ActivatedDate,
             . . . 
      FROM API.publisher_message_queue_detail mqd
      GROUP BY mqd.message_seq_id
     ) mqd
     USING (message_seq_id)
WHERE mq.status = 'N' AND mq.MESSAGE_TYPE = 'RetailerNewConnection';

【讨论】:

我尝试了您的第二个查询。为什么它会说“在预期的地方找不到 FROM 关键字”? 通过“发明语法”,您可能指的是 PIVOT 运算符,由 Oracle 在 11.1 版中“发明”。如果这就是您的意思,请注意 PIVOT (可能)比条件聚合更有效;条件聚合查询的SELECT 子句中的所有CASE 表达式必须单独评估,从而导致将同一列重复与不同的值进行比较。 PIVOT 实现似乎使用更有效的方式来完成相同的工作。 (我之所以说“出现”,是因为除了 Oracle 之外没有人知道,但可以看出它的性能要好一些。) @Kabilesh 。 . .您必须使用相同逻辑的类似行填写. . . 。确保from 之前没有逗号。

以上是关于SQL 中的 PIVOT 给出错误 - ORA-00933: SQL 命令未正确结束的主要内容,如果未能解决你的问题,请参考以下文章

SQL 中的 Pivot 语法错误,为啥我得到不正确的结果?

SQL Server 中的 PIVOT 不支持 Select 语句

ORA-0 [BEA][Oracle JDBC Driver] 未处理的 sql 类型

SQL Server 2008 中的 PIVOT / UNPIVOT

Pivot 中的 SQL 转换

如何将 SQL 中的列中的值 PIVOT 到新的列名中,然后在这些 PIVOT 列下列出其他列值?