2011-01-13 2 views
4

Ich habe die folgende Struktur:Wie wählt man FK als Header-Namen und Werte als Liste dieser Werte?

TABLE: Field 
ID | Name 
---|-------- 
1 | Email 
2 | City 

Und

TABLE: Answers 
ID | Field | Value  | User 
----------------------------------- 
1 | 1 | [email protected] | 3 
2 | 2 | abc   | 3 
3 | 1 | [email protected] | 4 
4 | 2 | qwe   | 4 

ich wählen wollen:

Email  | City 
------------------- 
[email protected] | abc 
[email protected] | qwe 

Wie kann ich es tun?

+1

Wie kann man sagen, dass [email protected] zu abc verwandt ist und [email protected] bezieht sich auf QWE? Ich sehe keine Beziehung in den gegebenen Daten. –

+0

@Joe Ich habe 'User' Spalte hinzugefügt, um dies zu simulieren ... – BrunoLM

+0

Ich nehme an, diese sind dynamisch? Keine feste Liste. –

Antwort

6

Sie können dies versuchen:

DECLARE @columns NVARCHAR(MAX) 

SELECT @columns = COALESCE(@columns + ',[' + cast(f.[Name] as varchar) + ']', 
'[' + CAST(f.[Name] as VARCHAR)+ ']') 
FROM Answers AS a INNER JOIN Field AS f ON a.[Field] = f.[ID] 
GROUP BY f.[Name] 

DECLARE @query NVARCHAR(MAX) 

SET @query = ' 
SELECT * FROM 
(SELECT f.[Name], a.[Value], a.[User] 
FROM Answers AS a INNER JOIN Field AS f ON a.[Field] 
= f.[ID]) AS s 
PIVOT (MAX(Value) FOR [Name] IN (' + @columns + ')) AS p' 

EXECUTE(@query); 
+1

+1 Warum nicht 'nvarchar (max)' though? –

+1

BTW - Sie sollten 'quote_name' verwenden, anstatt die eckigen Klammern selbst zu verketten, um korrekt mit allen Feldnamen umzugehen, die zufällig das Zeichen'] 'enthalten. –

0
SELECT A1.Value, A2.Value FROM Answers A1 JOIN Answers A2 on A1.User = A2.User 

"Self-Join". Aber dies ist ein nicht-generische Lösung, die brechen, wenn Sie Feld hinzufügen 3.

1
SELECT User, 
MAX(CASE WHEN field=1 THEN value END) AS [Email], 
MAX(CASE WHEN field=2 THEN value END) as [City] 
FROM test 
GROUP BY User; 

Sie können auch das gleiche tun PIVOT verwenden, aber ich persönlich fand die Syntax oben übersichtlicher und einfacher zu bedienen als PIVOT. Wenn Sie dynamische Felder haben, müssen Sie diese Abfrage auch generisch machen. Ich würde davon ausgehen, Funktion zu schaffen, die alle unterschiedlichen Werte in der ersten Tabelle analysiert, durchläuft sie und gibt eine richtige Abfrage (Sie müssen für jede ID in der ersten Tabelle anhängen MAX(CASE WHEN field=N THEN value END) AS [Field_N_Name]

1

Ich sehe nicht, wie Sie tun, dass in einer einzigen Anweisung select kann

Es ist ein wenig verwirrend, aber ich denke, das funktionieren könnte.

SELECT 
    External.Value as Email, 
    City 
FROM 
    Answers as External 
JOIN 
(
    SELECT 
     Answers.Value as City, 
     Answers.User 
    FROM 
     Answers 
    WHERE 
     Answers.Field = 2 
) AS Internal 
ON 
(External.User = Internal.User) 
WHERE 
    External.Field = 1 

Da die Säule das gleiche ist, ich bin zuerst die E-Mail auswählen und dann die Auswahl der Stadt und schließlich verbinden sie beide, so dass sie in der gleichen Ergebnisreihe erscheinen.

Verwandte Themen