sql >> Databáze >  >> RDS >> Mysql

Výběrový dotaz MySQL s názvem proměnného sloupce

Nejjednodušším řešením je použít dva samostatné dotazy.

Výsledek z prvního dotazu používáme k dynamickému generování textu SQL pro druhý dotaz.

mysql> SET @colname := '' ; 
mysql> SELECT t.rslt FROM table1 t WHERE t.id = 1 ORDER BY t.rslt LIMIT 1 INTO @colname ;

mysql> SET @sql := CONCAT('SELECT `',@colname,'` FROM table2 ORDER BY 1') ;
mysql> PREPARE stmt FROM @sql ; 
mysql> EXECUTE stmt ;

mysql> DEALLOCATE PREPARE stmt ;

N.B. včetně @colname jako součást textu SQL je dynamicky připravený SQL potenciální zranitelností SQL Injection.

Pokud je požadavkem provést něco podobného v kontextu single SQL, pak příkaz musí předvídat možné hodnoty, které mají být vráceny pro dotaz z tabulky1, a obsahovat explicitní odkazy na možné sloupce z tabulky2. Například něco takového:

  SELECT CASE ( SELECT t.rslt FROM table1 t WHERE t.id = 1 LIMIT 1 )
           WHEN 'r1' THEN r.r1 
           WHEN 'r2' THEN r.r2 
           WHEN 'r3' THEN r.r3 
           ELSE NULL
         END AS c2
    FROM table2 r
   ORDER BY ...

Toto není nutně nejefektivnější způsob, jak napsat dotaz, ale demonstruje vzor.

V rámci příkazu SQL musí být identifikátory (názvy tabulek, názvy sloupců, názvy funkcí) specifikovány explicitně; tyto nemohou být odvozeny dynamicky za běhu. Je to kvůli tomu, jak jsou příkazy SQL zpracovávány... analyzovat text SQL na syntaxi, poté analyzovat sémantiku (platné odkazy a oprávnění), vyhodnotit relativní náklady na dostupné přístupové cesty, vybrat plán provádění a pak tento plán provést.

To znamená, že chování pozorované u tohoto SQL je to, co očekáváme:

 SELECT (SELECT rslt FROM table1 WHERE id = 1) FROM table2

Připraví se text SQL a v době provádění je pro každý řádek v tabulce 2 poddotaz v SELECT seznam se provede. Pokud poddotaz vrátí skalární hodnotu, je vrácena skalární hodnota jako sloupec vnějšího dotazu. Hodnota vrácená poddotazem je hodnota , není (a nemůže být) vyhodnocen jako název sloupce.



  1. Přesměrování vložení založené na spouštěči Postgres bez přerušení RETURNING

  2. Mazání řádků pomocí MySQL LEFT JOIN

  3. Operátor SQL se nerovná (!=) pro začátečníky

  4. Nalezení přesné hodnoty z řetězce odděleného čárkou v PHP MySQL