Navrhuji přepsat příkaz tak, aby existoval pouze jeden argument vazby. Tento přístup je poněkud ošklivý, ale vrací sadu výsledků:
select max(col1)
, f_col2
from (
select col1
, f(? ,col2) as f_col2
from t
)
group
by f_col2
Tento přepsaný příkaz má odkaz pouze na jeden argument vazby, takže nyní DBMS vidí, že výrazy v klauzuli GROUP BY a v seznamu SELECT jsou totožné.
HTH
[EDIT]
(Přál bych si, aby existoval hezčí způsob, proto preferuji přístup pojmenovaného argumentu vazby, který používá Oracle. S ovladačem Perl DBI jsou poziční argumenty převedeny na pojmenované argumenty v příkazu skutečně odeslaném Oracle.)
Nejprve jsem v tom neviděl problém, nerozuměl jsem původní otázce. (Zřejmě to přehlédlo i několik dalších lidí.) Ale po provedení několika testovacích případů mi došlo, v čem je problém, jaká otázka funguje.
Uvidím, jestli mohu uvést problém:jak získat dva samostatné (poziční) argumenty vazby, aby se s nimi zacházelo (pomocí DBMS), jako by to byly dva odkazy na stejný (pojmenovaný) argument vazby.
DBMS očekává, že výraz v GROUP BY bude odpovídat výrazu v seznamu SELECT. Ale tyto dva výrazy jsou považovány za ODLIŠNÉ, i když jsou výrazy identické, když jediný rozdíl je v tom, že každý výraz odkazuje na jinou proměnnou vazby. (Můžeme předvést některé testovací případy, které alespoň některé DBMS umožní, ale existují obecnější případy, které vyvolá výjimku.)
V tuto chvíli krátká odpověď je, že mě to zarazilo. Navrhuji (což nemusí být skutečná odpověď na původní otázku) restrukturalizovat dotaz.
[/EDIT]
Mohu poskytnout více podrobností, pokud tento přístup nefunguje, nebo pokud máte nějaký jiný problém, jak to zjistit. Nebo pokud je problém s výkonem (vidím, že optimalizátor volí jiný plán pro přepsaný dotaz, i když vrací zadanou sadu výsledků. Pro další testování bychom opravdu potřebovali vědět, jaký DBMS, jaký ovladač, statistiky atd.)
UPRAVIT (o osm a půl roku později)
Další pokus o přepsání dotazu. Opět jediné řešení, se kterým přicházím, je dotaz s jedním zástupným symbolem vazby. Tentokrát jej vložíme do inline pohledu, který vrátí jeden řádek, a připojíme jej k t. Vidím, co to dělá; Nejsem si jistý, jak to uvidí optimalizátor Oracle. Můžeme chtít (nebo potřebovat) provést explicitní konverzi, např. TO_NUMBER(?) AS param
, TO_DATE(?,'...') AS param
, TO_CHAR(?) AS param
v závislosti na datovém typu parametru vazby a datovém typu, který chceme vracet z pohledu.)
Takto bych to udělal v MySQL. Původní dotaz v mé odpovědi provádí operaci spojení uvnitř vloženého zobrazení (odvozená tabulka MySQL ). A chceme se vyhnout materializaci tabulky odvozené z hughjass, pokud se tomu můžeme vyhnout. Pak znovu, MySQL pravděpodobně nechá původní dotaz klouzat tak dlouho jako sql_mode
nezahrnuje ONLY_FULL_GROUP_BY
. MySQL by nám také umožnilo vypustit 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)
Podle odpovědi od MadusankaD během posledních osmi let Oracle přidal podporu pro opětovné použití stejně pojmenovaných parametrů vazby v ovladači JDBC a zachování ekvivalence. (Netestoval jsem to, ale pokud to nyní funguje, pak skvělé.)