2011-01-10 19 views
0

Tabelle BenutzerSQL Server-Abfrage-Problem

Id Username 
    1 A 
    2 B 
    3 C 
    4 D 

Tabelle Rollen

Id UserId Role  Status  Expiration 
1 1  Admin  Active  01-01-2011 
2 2  Client  Active  02-02-2011 
3 3  Applicant Active  03-03-2011 
4 4  Client  Inactive  04-04-2011 

Ausgang:

A    B   C    D  -- this is the username 
Admin  Client  Applicant  Client  -- role of the username 
Active  Active  Active   inactive -- status of the username 
01-01-2011 02-02-2011 03-03-2011  04-04-2011 -- expiration of username 

Ich möchte das Ergebnis oben erreicht. Benutzer und Rollen Tabelle haben eine Eins-zu-eins-Beziehung.

Benutzername zusammen mit den Rollen Informationen sollten jeweils in einer Spalte sein. Zum Beispiel Benutzer A eine Rolle Informationen von Admin mit, Aktive und 01-01-2011 kam aus Rolle, Status, Ablauf Felder jeweils von Tabelle Rollen.

Haben Sie Hilfe, wie Sie dieses Ergebnis erreichen können?

+5

Wenn dies für einen Bericht ist, oder etwas ähnliches, sollten Sie besser tun, um diese Art zu tun, von der Formatierung in Ihrem Reporting-Tool und nicht in SQL. In SQL sind die Werte in jeder Spalte immer vom gleichen Typ - aber in Ihren Spalten sind Text und Daten vermischt. –

Antwort

0

Sie müssen beide UNPIVOT and PIVOT verwenden. UNPIVOT kann die Spalten Role, Status und Expiration in Zeilen konvertieren. Und PIVOT kann Benutzernamenzeilen in Spalten umwandeln.

WITH Roles (Id, UserId, Role, Status, Expiration) AS 
(
    SELECT 1, 1, 'Admin', 'Active', '01-01-2011' 
    UNION ALL SELECT 2, 2, 'Client', 'Active', '02-02-2011 ' 
    UNION ALL SELECT 3, 3, 'Applicant', 'Active', '03-03-2011' 
    UNION ALL SELECT 4 , 4, 'Client', 'Inactive', '04-04-2011' 
), 
[User] (Id, Username) AS 
(
    SELECT 1, 'A' 
    UNION ALL SELECT 2, 'B' 
    UNION ALL SELECT 3, 'C' 
    UNION ALL SELECT 4, 'D' 
) 
SELECT Fields.FieldId, 
    Pivoted.* 
FROM 
(
    SELECT [User].UserName, 
     CAST(Roles.Role AS nvarchar(100)) Role, 
     CAST(Roles.Status AS nvarchar(100)) Status, 
     CAST(Roles.Expiration AS nvarchar(100)) Expiration 
    FROM Roles 
    JOIN [User] ON [User].Id = Roles.UserId 
) RawData 
UNPIVOT (FieldValue FOR FieldName 
     IN ([Role], [Status], [Expiration])) Unpivoted 
PIVOT (MIN(FieldValue) FOR UserName IN ([A], [B], [C], [D])) Pivoted 
JOIN 
(
    SELECT 1, 'Role' 
    UNION ALL SELECT 2, 'Status' 
    UNION ALL SELECT 3, 'Expiration' 
) Fields (FieldId, FieldName) 
    ON Fields.FieldName = Pivoted.FieldName 
ORDER BY Fields.FieldId 

Ausgang:

FieldId FieldName A   B   C   D 
1  Role  Admin  Client  Applicant Client 
2  Status  Active  Active  Active  Inactive 
3  Expiration 01-01-2011 02-02-2011 03-03-2011 04-04-2011 
+0

wie die Anweisung dynamisch unter SELECT 1, 1, 'Admin', 'Aktiv', '01 -01-2011 ' UNION ALL SELECT 2, 2,' Client ',' Aktiv ', '02 -02- 2011 ' UNION ALLE WÄHLEN 3, 3,' Antragsteller ',' Aktiv ', '03 -03-2011' UNION ALLE WÄHLEN 4, 4, 'Client', 'Inaktiv', '04 -04-2011 ' – user335160

+0

Just entferne den gesamten Code zwischen "WITH" und "[User] (Id, Username)" –

0

Erste Setup die Beispieldaten in einer SQL-Skript

Declare @User table (ID int, Username varchar(50)) 
Insert Into @User (id, username) values (1,'A') 
Insert Into @User (id, username) values (2,'B') 
Insert Into @User (id, username) values (3,'C') 
Insert Into @User (id, username) values (4,'D') 
Declare @role table (ID int, UserID int, Role varchar(50), Status varchar(50), Expiration DateTime) 
Insert Into @role (id, UserID, Role, Status, Expiration) values (1, 1, 'Admin', 'Active', '01-01-2011') 
Insert Into @role (id, UserID, Role, Status, Expiration) values (2, 2, 'Client',  'Active', '02-02-2011') 
Insert Into @role (id, UserID, Role, Status, Expiration) values (3, 3, 'Applicant', 'Active', '03-03-2011') 
Insert Into @role (id, UserID, Role, Status, Expiration) values (4, 4, 'Client', 'Inactive', '04-04-2011') 

Dann legte unter der folgenden Eigenschaften und die Menge laufen, werden Sie sehen, warum es nicht ein sehr schöne Art, Pivot zu benutzen.

SELECT 
[A], [B], [C], [D] 
FROM 
(Select Username, Role, Status, Expiration 
FROM @User u 
Inner Join @role r 
On u.ID = r.UserID) AS SourceTable 
PIVOT 
(
Max(Role) 
FOR Username IN ([A], [B], [C], [D]) 
) AS PivotTable1; 

Ausgabe

Admin NULL NULL NULL 
NULL Client NULL NULL 
NULL NULL Applicant NULL 
NULL NULL NULL Client 

Essentiatilly Sie benötigen mehrere schwenkt zu kombinieren um den gewünschten Effekt zu bekommen, und es Gruppen alle Benutzer in einer einzigen Zeile, so dass es nicht ein sehr einfaches Ergebnis macht einstellen.

Haben Sie die Verwendung von For XML in Betracht gezogen?

Select Username, Role, Status, Expiration 
FROM @User u 
Inner Join @role r 
On u.ID = r.UserID 
For XML Auto 

Ausgang ...

<u Username="A"> 
    <r Role="Admin" Status="Active" Expiration="2011-01-01T00:00:00" /> 
</u> 
<u Username="B"> 
    <r Role="Client" Status="Active" Expiration="2011-02-02T00:00:00" /> 
</u> 
<u Username="C"> 
    <r Role="Applicant" Status="Active" Expiration="2011-03-03T00:00:00" /> 
</u> 
<u Username="D"> 
    <r Role="Client" Status="Inactive" Expiration="2011-04-04T00:00:00" /> 
</u>