Das läuft unter dem Begriff “pivot” oder “crosstab” - etwas was in SQL grundsätzlich nicht so einfach ist, das eine der Limitierungen der Sprache ist, dass die Anzahl (und Datentypen) einer Abfrage vor dem Ausführen eine Abfrage fest stehen muss.
Deswegen muss man diese Art von Abfragen immer anpassen wenn zusätzliche Spalten dazukommen sollen. Aus diesem Grund ist es im Regelfall wesentlich einfacher und flexibler dies in der Anwendung zu machen, welche die Daten anzeigt. Nicht schon beim Lesen der Daten.
Normalerweise verwendet man dafür bedingte Aggregation:
select max(val) filter (where "key" = 'key1') as key1,
max(val) filter (where "key" = 'key2') as key2,
max(val) filter (where "key" = 'key3') as key3,
max(val) filter (where "key" = 'key4') as key4
from test
where employee = 'emp1';
Da für jeden “key” (hoffentlich) immer nur ein Wert vorhanden sein kann, wird dieser mittels max() und filter() “rausgepickt”.
Das kann man dann auch für jeden Datensatz der Tabelle machen, wenn man ein GROUP BY mit dazu nimmt:
select employee,
max(val) filter (where "key" = 'key1') as key1,
max(val) filter (where "key" = 'key2') as key2,
max(val) filter (where "key" = 'key3') as key3,
max(val) filter (where "key" = 'key4') as key4
from test
group by employee;
danke für die Antworten.
Also bisher hatte ich es so:
$sql = "SELECT key, val FROM mydefaults WHERE employee = 12 AND key = 'asterisk_passwd' OR key = 'ip_asterisk' OR key = 'user_external_context' OR key ='user_internal_phone' OR key = 'external_contexts' OR key = 'internal_phones'";
$result = $GLOBALS['dbh']->getAll( $sql );
$resultArray = array();
foreach( $result as $value ) $resultArray[$value['key']] = $value['val'];
Ich wollte die Logik in SQL implementieren. @akretschmer
Wie kann ich das dynamisch in SQL realisieren?
Ich möchte in der Abfrage lediglich den employee und die keys angeben und mit getOne die Daten holen.
Wenn der entsprechende key nicht vorhanden ist wird null oder ein leerer String zurückgegeben.
Etwa so:
“wähle alles ( mache aus den Zeilen des Employees 12 eine Tabelle mit den Spaltennamen der angegebenen Keys (key1, key2, key3) und liefere deren Values) ;”
Wie @castorp schon sagte: es ist einfacher, sich aus PG nur ein Objekt mit allen Daten geben zu lassen, und in der Applikation damit zu hantieren. Zum Beispiel JSON:
test=*# select * from test;
id | key | val | employee
----+------+--------+----------
1 | key1 | value1 | emp1
2 | key2 | value2 | emp1
3 | key3 | value3 | emp1
4 | key4 | value4 | emp1
(4 rows)
test=*# select to_json(r) from (select json_agg(t.key) as key, json_agg(t.val) as val from test t) r;
to_json
-----------------------------------------------------------------------------------------
{"key":["key1", "key2", "key3", "key4"],"val":["value1", "value2", "value3", "value4"]}
(1 row)