2 Stimmen

Erzeugen eines "Streudiagramms" von Mitgliedern gegen Mengen aus einer SQL-Abfrage

Ich habe eine staff Datenbanktabelle, die die Mitarbeiter enthält, mit user_no y user_name Spalten. Ich habe eine andere, department Tabelle mit den Abteilungen, in denen Mitarbeiter Mitglied sein können, mit dept_no y dept_name als Spalten.

Da Mitarbeiter in mehreren Abteilungen tätig sein können, habe ich eine dritte, staff_dept Tabelle mit einer user_no Spalte und eine dept_no Spalte, die die Primärschlüssel dieser beiden anderen Tabellen sind. Diese Tabelle zeigt, zu welchen Abteilungen jeder Mitarbeiter gehört, und enthält eine Zeile für jede Kreuzung zwischen Benutzer und Abteilung.

Ich möchte eine Ausgabe in Form einer Kalkulationstabelle (CSV-Datei, was auch immer; ich werde die Ergebnisse in eine brauchbare Form bringen, nachdem ich sie erhalten habe) mit einer Spalte für jede Abteilung und einer Zeile für jeden Benutzer, mit einer X die an jeder Kreuzung auftreten, wie in staff_dept .

Kann ich eine einzige SQL-Abfrage schreiben, die dieses Ergebnis erzielt, oder muss ich "richtig" programmieren (denn ein "richtiges" Programm ist es erst, wenn man drei oder vier Abfragen verschachtelt hat)? for Schleifen), um diese Daten zu sammeln und zu formatieren?

3 Stimmen

Welche rdbms? oracle? sql-server? mysql? postgre? db2? access?

2 Stimmen

5voto

mellamokb Punkte 55046

Dies kann mit einer PIVOT-Tabelle (mit SQL Server) geschehen:

SELECT user_name, [dept1name], [dept2name], [dept3name], ...
FROM
    (SELECT s.user_name, d.dept_name,
     case when sd.user_no is not null then 'X' else '' end as matches
     from staff s
     cross join department d
     left join staff_dept sd on s.user_no = sd.user_no and d.dept_no = sd.dept_no
    ) AS s
PIVOT
(
    min(matches)
    FOR dept_name IN ([dept1name], [dept2name], [dept3name], ...)
) AS pvt
order by user_name

Demo: http://www.sqlfiddle.com/#!3/c136d/5

Editar : Um die PIVOT-Abfrage dynamisch aus der Liste der Abteilungen in der Tabelle zu generieren, verwenden Sie dynamisches SQL, d. h. Sie generieren den Code in einer Variablen und verwenden sp_executesql gespeicherte Hilfsprozedur. Hier ist ein Beispiel: http://www.sqlfiddle.com/#!3/c136d/14

0 Stimmen

Das ist sehr cool. Gibt es eine Möglichkeit, das so zu machen, dass man nicht alle Abteilungsnamen als Spalten eintippen muss? Eine Möglichkeit, die Zeilen als Spalten auszuwählen?

0 Stimmen

@Dan: Ja, mit dynamisch generiertem SQL-Code. Ich werde ein Beispiel hinzufügen.

0 Stimmen

Danke. Das ist etwas zu hoch für mich, aber ich werde wissen, was ich nachschlagen muss, wenn ich in eine ähnliche Situation gerate. Ist der dynamische Teil rekursiv und die coalesce() nur, um den ersten Fall zu behandeln, wenn @sql noch NULL ist oder bin ich völlig aus?

1voto

Philip Kelley Punkte 38051

In SQL Server (wenn Sie SQL Server verwenden), würde ich mit einer vollständigen äußeren Verknüpfung beginnen (um die tous Mitarbeiter und Abteilungen, nicht nur die, die an der Beziehung beteiligt sind), fügen Sie dies in eine Pivot-Anweisung ein, um alle Abteilungen in Spalten zu pivotieren, und erstellen Sie dann ein kurzes Skript, um diese SELECT-Anweisung zu generieren und dynamisch auszuführen (da die durch eine Pivot-Anweisung erstellten Spalten fest kodiert sein müssen, können sie zur Laufzeit nicht dynamisch generiert werden).

Hier ist ein Beispiel -- Es handelt sich um eine Unpivot-Anweisung, aber das Konzept ist so ziemlich dasselbe.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X