sql >> Database >  >> RDS >> Mysql

MySQL-selectiequery met variabele kolomnaam

De eenvoudigste oplossing is om twee afzonderlijke zoekopdrachten te gebruiken.

We gebruiken het resultaat van de eerste query om dynamisch de SQL-tekst voor de tweede query te genereren.

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 ;

NB inclusief @colname als onderdeel van de SQL-tekst is dynamisch voorbereide SQL een potentiële kwetsbaarheid voor SQL-injectie.

Als de vereiste is om iets soortgelijks gedaan te krijgen in de context van een enkele SQL-instructie, dan moet de instructie anticiperen op de mogelijke waarden die moeten worden geretourneerd voor de query uit tabel1, en expliciete verwijzingen naar de mogelijke kolommen uit tabel2 bevatten. Bijvoorbeeld zoiets als dit:

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

Dit is niet per se de meest efficiënte manier om de query te schrijven, maar het toont het patroon aan.

Binnen een SQL-statement moeten de identifiers (tabelnamen, kolomnamen, functienamen) expliciet worden opgegeven; deze kunnen tijdens runtime niet dynamisch worden afgeleid. Dit komt door de manier waarop SQL-instructies worden verwerkt... het ontleden van de SQL-tekst op syntaxis, vervolgens ontleden op semantiek (geldige verwijzingen en privileges), het evalueren van de relatieve kosten voor beschikbare toegangspaden, het selecteren van een uitvoeringsplan en vervolgens het uitvoeren van dat plan.

Dat wil zeggen, het waargenomen gedrag met deze SQL is wat we verwachten:

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

De SQL-tekst wordt voorbereid, en tijdens de uitvoering, voor elke rij in tabel2, de subquery in de SELECT lijst wordt uitgevoerd. Als de subquery een scalaire waarde retourneert, wordt de scalaire waarde geretourneerd als een kolom van de buitenste query. De waarde die wordt geretourneerd door de subquery is een waarde , het is niet (en kan niet worden) geëvalueerd als een kolomnaam.



  1. php gebruiken om GROUP_CONCAT('column x') waarden te retourneren

  2. Hoe het Query-resultaat in een variabele op te slaan met mysql

  3. Cheatsheet voor MySQL-prestaties

  4. Selecteer rijen waar pivot ALLE ID's heeft