Righe SQL per le colonne
-
19-09-2019 - |
Domanda
Ho una tabella e desidera trasporre i suoi filari di colonne, simile a una tabella pivot, ma senza che riassume.
Per esempio io ho le seguenti tabelle:
Question
--QuestionID
--QuestionText
Response
--ResponseID
--ResponseText
--QuestionID
Fondamentalmente voglio essere in grado di creare una tabella di qualcosa di dinamico come:
Question 1 Text | Question 2 Text | Question 3 Text
---------------------------------------------------
Response 1.1 Text | Response Text 1.2 | Response 1.3
Response 2.1 Text | Response Text 2.2 | Response 2.3
Response 3.1 Text | Response Text 3.2 | Response 3.3
Response 4.1 Text | Response Text 4.2 | Response 4.3
Il requisito principale sarebbe non so in fase di progettazione ciò che il testo della domanda sarà.
Si prega di qualcuno può aiutarmi - sto tirando fuori i miei capelli: Sistema operativo
In sostanza si può garantire che non ci sarà una risposta per ogni domanda corrispondente in questo scenario.
Soluzione
Non si può farlo con SQL
(tranne che con le query dinamiche), se non si conosce il numero di colonne (i. E. Questions) in fase di progettazione.
Si dovrebbe estrarre i dati che si desidera in formato tabulare e poi elaborarlo sul lato client:
SELECT *
FROM Question
LEFT OUTER JOIN
Response
ON Response.QuestionId = Question.QuestionID
o, probabilmente, questo (in SQL Server 2005+
, Oracle 8i+
e PostgreSQL 8.4+
):
SELECT *
FROM (
SELECT q.*, ROW_NUMBER() OVER (ORDER BY questionID) AS rn
FROM Question q
) q
LEFT OUTER JOIN
(
SELECT r.*, ROW_NUMBER() OVER (PARTITION BY questionID ORDER BY ResponseID) AS rn
FROM Response r
) r
ON r.QuestionId = q.QuestionID
AND q.rn = r.rn
ORDER BY
q.rn, q.QuestionID
La seconda interrogazione vi darà i risultati di questo modulo (a condizione che avete 4
domande):
rn question response
--- --- ---
1 Question 1 Response 1.1
1 Question 2 Response 2.1
1 Question 3 Response 3.1
1 Question 4 Response 4.1
2 Question 1 Response 1.2
2 Question 2 Response 2.2
2 Question 3 NULL
2 Question 4 Response 4.2
3 Question 1 NULL
3 Question 2 NULL
3 Question 3 Response 3.3
3 Question 4 NULL
, questo è il risultato sarà i dati in forma tabellare, con rn
marcatura il numero di riga.
Ogni volta che si vede il rn
cambiando sul client, è sufficiente chiudere <tr>
e aprire quello nuovo.
Si può tranquillamente mettere uno del <td>
per riga di risultati, dal momento che lo stesso numero o le righe è garantito da restituire per ogni rn
Questo è un bel domanda frequente.
SQL
non solo uno strumento di diritto di restituire i dati con il numero dinamica delle colonne.
SQL
opera su insiemi, e il layout delle colonne è una proprietà implicita di un insieme.
Si dovrebbe definire il layout del set che si desidera ottenere in fase di progettazione, come si definisce il tipo di dati di un varible in C
.
C
funziona con le variabili rigorosamente definite, SQL
lavora con i set rigorosamente definite.
Si noti che non sto dicendo che è il miglior metodo possibile. E 'solo le opere SQL
modo.
Aggiornamento:
In SQL Server
, si può tirare la tabella in forma HTML
destra, fuori dalla banca dati:
WITH a AS
(
SELECT a.*, ROW_NUMBER() OVER (PARTITION BY question_id ORDER BY id) AS rn
FROM answer a
),
rows AS (
SELECT ROW_NUMBER() OVER (ORDER BY id) AS rn
FROM answer a
WHERE question_id =
(
SELECT TOP 1 question_id
FROM answer a
GROUP BY
question_id
ORDER BY
COUNT(*) DESC
)
)
SELECT (
SELECT COALESCE(a.value, '')
FROM question q
LEFT JOIN
a
ON a.rn = rows.rn
AND a.question_id = q.id
FOR XML PATH ('td'), TYPE
) AS tr
FROM rows
FOR XML PATH(''), ROOT('table')
Vedere questa voce nel mio blog per maggiori dettagli:
Altri suggerimenti
Fate il vostro raggruppamento e aggregazione prima, usando la risposta di Quassnoi come un risultato intermedio.
contingenza deve essere fatto solo quando non è più intenzione di fare set orientato operatons sui risultati sono. Alcuni dialetti SQL sono parole chiave come PIVOT, trasformare o incrociare per raggiungere questo obiettivo, ma probabilmente siete meglio utilizzando XSLT.