2016-06-08 65 views
5

Utilizzando l'un char-fuso in un gruppo-by risultati clausola qualcosa di inaspettato:Oracle SQL - gruppo da char gettato

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)); 

Il risultato è (lungo 10 caratteri) 'Abc '. Intuitivamente, avrei aspettato Oracle per restituire una delle seguenti operazioni:

  • Errore: 'non gruppo-by espressione', come il gruppo-by clausola è altro che la clausola selezione
  • risultati di lunghezza 2 'Ab'.

Sostituire cast(col as char(2)) con cast(col as char(3)), Oracle restituisce un errore "non un'espressione di gruppo". Questo, di nuovo, è un comportamento molto strano.

Come può essere spiegato? Qual è la ragione dietro a questo?

Sto usando Oracle SQL 11g.

+0

Ho appena testato su 11g e produce gli stessi risultati per i valori 1-11, tranne che per 3. Molto strano. Per me, questo sembra un insetto. Il ritorno dovrebbe essere "Ab". Il valore previsto viene restituito, se si utilizza una funzione di aggregazione. –

+0

Lo stesso in Oracle 12 – sstan

+0

Perché stai utilizzando il gruppo in una query che non utilizza la funzione di aggregazione? – scaisEdge

risposta

2

Come detto sopra, penso che ci sia un malinteso in corso. oO

non riesco a spiegare il motivo per cui si sta facendo questo, ma qui è il modello per il tipo di query avete:

Se generalizzare un po 'come questo, dove [A] e [B] sono interi , e [STRING] è qualunque testo che si desidera:

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])); 

sembra che questo non funziona sempre, se una delle due condizioni di seguito è vero (ci possono essere altri):

  1. (LUNGHEZZA ([ STRING]) < [B] O L Ength ([STRING]> [B]) e [A] = LUNGHEZZA ([String])
  2. (LUNGHEZZA ([String]) = [B] e [A] <> LUNGHEZZA ([String]))

In caso contrario, restituirà una riga.

Ma se si prende il vostro esempio che corre e utilizzarlo in un'istruzione CREATE TABLE, sta andando a fallire in quanto imposta la larghezza della colonna di essere il 2 e non può andare bene la stringa di 3 caratteri in arrivo.

per aggiungere alla stranezza, se si aggiunge qualcosa all'inizio e alla fine della stringa in questo modo:

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])); 

questo funziona solo se [a]> = [B], altrimenti fallisce l'ORA -01489: il risultato della concatenazione di stringhe è troppo lungo.

Curioso ...

+0

Grazie per la risposta e l'astrazione del problema. In effetti è ancora un comportamento molto strano. Non segnano la risposta come corretta, poiché è più un'aggiunta alla mia domanda che una spiegazione. –