oracle通过警告解码组

Posted

技术标签:

【中文标题】oracle通过警告解码组【英文标题】:oracle decode group by warning 【发布时间】:2018-04-16 10:21:14 【问题描述】:

我有这个代码

for x_eo in ( select decode(mod(card_name_id,2),0,1,1,2) e_o, count(*) nr 
                        from  rp_Deck where session_id=p_session_id_in 
                       and position<=35 group by mod(card_name_id,2) )

我收到 sqldeveloper 警告,提示选择列表与分组依据不一致。 开发者给了我解决方案:

select decode(mod(card_name_id,2),0,1,1,2) e_o, count(*) nr 
                        from  rp_Deck where session_id=p_session_id_in 
                       and position<=35 group by mod(card_name_id,2), card_name_id, 2, decode(mod(card_name_id,2),0,1,1,2) )

这两个 group by 有什么区别? 谢谢!

【问题讨论】:

【参考方案1】:

一般来说,当您在语句中使用GROUP BY 时,所有值都需要:

常量; 在聚合函数中;或 在GROUP BY 子句中。

SQL Developer 没有意识到decode(value_mod_2,0,1,1,2) 实际上只是将值加 1 并且不会更改项到组的分配,因此,由于它既不是常量也不是聚合函数,它期望整个函数在GROUP BY 子句中。

就我个人而言,我会写成:

select mod(card_name_id,2) + 1 e_o,
       count(*) nr 
from   rp_Deck
where  session_id=p_session_id_in 
and    position<=35
group by mod(card_name_id,2)

+ 1 是一个常量,因此不需要在 GROUP BY 子句中)

SQL Developer 提出的解决方案是错误的:

select decode(mod(card_name_id,2),0,1,1,2) e_o,
       count(*) nr 
from   rp_Deck
where  session_id=p_session_id_in 
and    position<=35
group by
       mod(card_name_id,2),
       card_name_id,
       2,
       decode(mod(card_name_id,2),0,1,1,2)

实际上与仅按最细粒度分组进行分组相同,因此:

group by card_name_id;

这不是您想要分组的对象。为了与您的原始查询的预期输出相同,它应该提出如下内容:

group by
       mod(card_name_id,2),
       decode(mod(card_name_id,2),0,1,1,2)

或更简单地说:

group by
       decode(mod(card_name_id,2),0,1,1,2)

【讨论】:

以上是关于oracle通过警告解码组的主要内容,如果未能解决你的问题,请参考以下文章

编译过程时出现oracle错误

oracle数据库的警告日志如何查看

Oracle - 通过左连接将多行组合到列

Jackcess 解码不支持警告

不是组表达式:对 Oracle 查询进行故障排除

警告:根:某些字符无法解码,并被替换为替换字符。带有请求和 Beastuifulsoup