SELECT q.id, d.key, d.value
FROM q
JOIN json_each_text(q.data) d ON true
ORDER BY 1, 2;
La función json_each_text() es una función de devolución establecida, por lo que debe usarla como fuente de fila. El resultado de la función está aquí unido lateralmente
a la tabla q , lo que significa que para cada fila de la tabla, cada (key, value) par de los data la columna se une solo a esa fila, por lo que la relación entre la fila original y las filas formadas a partir del json se mantiene el objeto.
La tabla q también puede ser una subconsulta muy complicada (o un VALUES cláusula, como en su pregunta). En la función, la columna adecuada se usa a partir del resultado de evaluar esa subconsulta, por lo que solo usa una referencia al alias de la subconsulta y la columna (alias de la) en la subconsulta.