sql >> Databasteknik >  >> RDS >> Mysql

MySQL-valsfråga med variabelkolumnnamn

Den enklaste lösningen är att använda två separata frågor.

Vi använder resultatet från den första frågan för att dynamiskt generera SQL-texten för den andra frågan.

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. inklusive @colname som en del av SQL-texten, dynamiskt förberedd SQL, är en potentiell SQL Injection-sårbarhet.

Om kravet är att få något liknande gjort inom ramen för en singel SQL-sats, då måste satsen förutse de möjliga värden som ska returneras för frågan från tabell1 och inkludera explicita referenser till möjliga kolumner från tabell2. Till exempel något sånt här:

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

Detta är inte nödvändigtvis det mest effektiva sättet att skriva frågan, men det visar mönstret.

I en SQL-sats måste identifierarna (tabellnamn, kolumnnamn, funktionsnamn) anges explicit; dessa kan inte härledas dynamiskt under körning. Detta beror på hur SQL-satser bearbetas... tolka SQL-texten för syntax, sedan tolka för semantik (giltiga referenser och privilegier), utvärdera relativ kostnad för tillgängliga åtkomstvägar, välja en exekveringsplan och sedan exekvera den planen.

Det vill säga beteendet som observeras med denna SQL är vad vi förväntar oss:

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

SQL-texten förbereds, och vid körningstidpunkten, för varje rad i tabell2, underfrågan i SELECT listan körs. Om underfrågan returnerar ett skalärt värde, returneras det skalära värdet som en kolumn i den yttre frågan. Värdet som returneras av underfrågan är ett värde , det är inte (och kan inte utvärderas) som ett kolumnnamn.



  1. SELECT från tabell med Variing IN-listan i WHERE-satsen

  2. Orsaker till MySQL-fel 2014 Kan inte köra frågor medan andra obuffrade frågor är aktiva

  3. uppföljningstabell utan kolumn "id"

  4. NULL vs DEFAULT NULL vs NULL DEFAULT NULL i MYSQL-kolumnskapande?