sql >> Database teknologi >  >> RDS >> Mysql

MySQL-valgsforespørgsel med variabel kolonnenavn

Den enkleste løsning er at bruge to separate forespørgsler.

Vi bruger resultatet fra den første forespørgsel til dynamisk at generere SQL-teksten for den anden forespørgsel.

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 af SQL-teksten, dynamisk forberedt SQL, er en potentiel SQL Injection-sårbarhed.

Hvis kravet er at få lavet noget lignende i sammenhæng med en enkelt SQL-sætning, så skal sætningen forudse de mulige værdier, der skal returneres for forespørgslen fra tabel1, og inkludere eksplicitte referencer til de mulige kolonner fra tabel2. For eksempel noget som dette:

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

Dette er ikke nødvendigvis den mest effektive måde at skrive forespørgslen på, men det demonstrerer mønsteret.

Inden for en SQL-sætning skal identifikatorerne (tabelnavne, kolonnenavne, funktionsnavne) angives eksplicit; disse kan ikke udledes dynamisk under kørsel. Dette er på grund af, hvordan SQL-sætninger behandles... parsing af SQL-teksten til syntaks, derefter parsing for semantik (gyldige referencer og privilegier), evaluering af relative omkostninger for tilgængelige adgangsstier, valg af en eksekveringsplan og udførelse af denne plan.

Det vil sige, at den adfærd, der observeres med denne SQL, er, hvad vi forventer:

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

SQL-teksten forberedes, og ved udførelsestidspunktet for hver række i tabel2, underforespørgslen i SELECT listen udføres. Hvis underforespørgslen returnerer en skalær værdi, returneres den skalære værdi som en kolonne i den ydre forespørgsel. Den værdi, der returneres af underforespørgslen, er en værdi , det er ikke (og kan ikke) evalueres som et kolonnenavn.



  1. Omdøb outfil med dato i mysql

  2. Oracle RAC på tredjepartsskyer

  3. Sådan får du aktuel dato og tid i MySQL

  4. Se min 'Optimering af Microsoft Access med SQL Server'-præsentation