简体   繁体   English

Oracle SQL - 由char cast组

[英]Oracle SQL - group by char cast

Using the a char-cast in a group-by clause results something unexpected: 在group-by子句中使用char-cast会导致意外情况:

select cast(col as char(2)) from (
  select 'Abc' as col from dual
  union all
  select 'Abc' as col from dual
) group by cast(col as char(10));

The result is 'Abc ' (10 characters long). 结果是'Abc ' (长10个字符)。 Intuitively, I would have expected Oracle to return one of the following: 直观地说,我原以为Oracle会返回以下其中一项:

  • An error: 'not a group-by expression', as the group-by clause is another than the selection clause 错误:'not group-by expression',因为group-by子句不是selection子句
  • A result of length 2 'Ab' . 长度为'Ab'

Replacing cast(col as char(2)) with cast(col as char(3)) , Oracle returns an error 'not a group-by expression'. cast(col as char(2))替换cast(col as char(2)) cast(col as char(3)) ,Oracle返回错误'而不是group-by表达式'。 This, again is a very strange behavior. 这也是一种非常奇怪的行为。

How can this be explained? 怎么解释这个? What's the reason behind it? 它背后的原因是什么?

I'm using Oracle SQL 11g. 我正在使用Oracle SQL 11g。

As was mentioned above, I think there is a misunderstanding going on. 如上所述,我认为存在误解。 oO OO

I can't explain why it's doing this, but here's the pattern for the type of query you have: 我无法解释为什么会这样做,但这里是您所拥有的查询类型的模式:

If you generalize it a bit like this, where [A] and [B] are integers, and [STRING] is whatever text you want: 如果你有点像这样概括,其中[A]和[B]是整数,[STRING]是你想要的任何文本:

select cast(col as char([A])) from (
  select '[STRING]' as col from dual
  union all
  select '[STRING]' as col from dual
) group by cast(col as char([B]));

it looks like this always fails if one of the two conditions below is true (there may be others): 如果以下两个条件中的一个为真(可能还有其他条件),它看起来总是会失败:

  1. ( LENGTH([STRING]) < [B] OR LENGTH([STRING] > [B]) and [A] = LENGTH([STRING]) (长度([STRING])<[B] OR LENGTH([STRING]> [B])和[A] = LENGTH([STRING])
  2. ( LENGTH([STRING]) = [B] AND [A] <> LENGTH([STRING]) ) (长度([STRING])= [B]和[A] <>长度([STRING]))

Otherwise, it'll return a row. 否则,它将返回一行。

But if you take your example that runs and use it in a CREATE TABLE statement, it's going to fail as it sets up the column width to be the 2 and can't fit the 3 character string coming in. 但是如果你把你的例子运行并在CREATE TABLE语句中使用它,那么它将失败,因为它将列宽设置为2并且不能适应进来的3个字符串。

To add to the oddity, if you append something at the start and the end of the string like this: 为了增加奇怪性,如果你在字符串的开头和结尾添加一些东西,如下所示:

select '\*'||cast(col as char([A]))||'\*' from (
  select '[STRING]' as col from dual
  union all
  select '[STRING]' as col from dual
) group by cast(col as char([B]));

This will only work if [A] >= [B], otherwise it fails on ORA-01489: result of string concatenation is too long. 这仅在[A]> = [B]时有效,否则在ORA-01489上失败:字符串连接的结果太长。

Curious... 好奇...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM