sql >> Databáze >  >> RDS >> Oracle

Je možné použít GROUP BY s proměnnými vazby?

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é.)



  1. Jak provést aktualizaci + připojit se k PostgreSQL?

  2. Jak naplnit gridview pomocí mysql?

  3. Najděte a nahraďte řetězec uvnitř BLOB for Work nebo souboru Excel

  4. Vytváření dočasných tabulek v MySQL Stored Procedure