Sugiro reescrever a instrução para que haja apenas um argumento de ligação. Essa abordagem é meio feia, mas retorna o conjunto de resultados:
select max(col1)
, f_col2
from (
select col1
, f(? ,col2) as f_col2
from t
)
group
by f_col2
Essa instrução reescrita tem uma referência a apenas um único argumento de ligação, então agora o DBMS vê as expressões na cláusula GROUP BY e a lista SELECT são idênticas.
HTH
[EDITAR]
(Gostaria que houvesse uma maneira mais bonita, é por isso que prefiro a abordagem de argumento de ligação nomeado que o Oracle usa. Com o driver Perl DBI, os argumentos posicionais são convertidos em argumentos nomeados na instrução realmente enviada ao Oracle.)
Eu não vi o problema no início, eu não entendi a pergunta original. (Aparentemente, várias outras pessoas também não perceberam.) Mas depois de executar alguns casos de teste, percebi qual era o problema, qual era a pergunta que estava funcionando.
Deixe-me ver se posso expor o problema:como obter dois argumentos de ligação separados (posicionais) a serem tratados (pelo DBMS) como se fossem duas referências ao mesmo argumento de ligação (nomeado).
O DBMS espera que a expressão no GROUP BY corresponda à expressão na lista SELECT. Mas as duas expressões são consideradas DIFERENTES mesmo quando as expressões são idênticas, quando a única diferença é que cada expressão faz referência a uma variável de ligação diferente. (Podemos demonstrar alguns casos de teste que pelo menos alguns DBMS permitirão, mas há casos mais gerais que levantarão uma exceção.)
Neste ponto, a resposta curta é, isso me deixou perplexo. A sugestão que tenho (que pode não ser uma resposta real para a pergunta original) é reestruturar a consulta.
[/EDITAR]
Posso fornecer mais detalhes se essa abordagem não funcionar ou se você tiver algum outro problema para descobrir. Ou se houver um problema com o desempenho (eu posso ver o otimizador escolhendo um plano diferente para a consulta reescrita, mesmo que ele retorne o conjunto de resultados especificado. Para testes adicionais, realmente precisamos saber qual DBMS, qual driver, estatísticas, etc)
EDITAR (oito anos e meio depois)
Outra tentativa de reescrever a consulta. Novamente, a única solução que encontrei é uma consulta com um marcador de posição de vinculação. Desta vez, colocamos em uma visualização em linha que retorna uma única linha e a associamos a t. Eu posso ver o que está fazendo; Não tenho certeza de como o otimizador do Oracle verá isso. Podemos querer (ou precisar) fazer uma conversão explícita, por exemplo.
TO_NUMBER(?) AS param
, TO_DATE(?,'...') AS param
, TO_CHAR(?) AS param
, dependendo do tipo de dados do parâmetro de ligação e do tipo de dados que queremos que seja retornado a partir da exibição.) É assim que eu faria isso no MySQL. A consulta original na minha resposta faz a operação de junção dentro da visualização em linha (MySQL tabela derivada ). E queremos evitar a materialização de uma tabela derivada de hughjass se pudermos evitá-la. Então, novamente, o MySQL provavelmente deixaria a consulta original deslizar enquanto
sql_mode
não inclui ONLY_FULL_GROUP_BY
. O MySQL também nos permitiria eliminar o FROM DUAL
) SELECT MAX(t.col1)
, f( v.param ,t.col2)
FROM t
CROSS
JOIN ( SELECT ? AS param FROM DUAL) v
GROUP
BY f( v.param ,t.col2)
De acordo com a resposta de MadusankaD, nos últimos oito anos, a Oracle adicionou suporte para reutilizar os mesmos parâmetros de ligação nomeados no driver JDBC e manter a equivalência. (Eu não testei isso, mas se isso funcionar agora, então ótimo.)