Laden...

Zwei Pivotisierte Spalten im Wechsel ausgeben

Erstellt von Palladin007 vor 10 Jahren Letzter Beitrag vor 10 Jahren 1.155 Views
Palladin007 Themenstarter:in
2.078 Beiträge seit 2012
vor 10 Jahren
Zwei Pivotisierte Spalten im Wechsel ausgeben

verwendetes Datenbanksystem: Ms SQL

Moin,

ich habe hier eine Tabelle mit drei Spalte: StadtId, StraßeName, StraßeTyp
Die Tabelle ist via Join zusammen gesammelt und muss nun aufbereitet werden.

Jede Stadt kann mehrere Straßen haben, jede Straße hat einen Typ.

Die vorher zusammen gelegte Tabelle sieht so aus:

StadtId | Reihenfolge | StraßeName | StraßeTyp
--------|-------------|------------|--------------
123     | 1           | Name1      | Alee
--------|-------------|------------|--------------
123     | 2           | Name2      | Hauptstraße
--------|-------------|------------|--------------
123     | X           | Name3      | Nebenstraße

Das Ergebnis soll so aussehen:

StadtId  | Straße 1 | Straße 1 Typ | Straße 2 | Straße 2 Typ | Straße X | Straße X Typ
---------|----------|--------------|----------|--------------|----------|--------------
123      | Name1    | Alee         | Name2    | Hauptstraße  | Name3    | Nebenstraße

Wenn ich nur die Reihenfolge und den Namen hätte, ließe sich das relativ einfach mit der Pivot-Funktion regeln. Ich lese dann vorher die Anzahl Straßen aus, baue mir daraus die neuen Spalten-Namen zusammen und generiere mit dessen Hilfe dann das Sql-Statement, was mir dann die gewollte Tabelle aus gibt.

Da ich hier aber jetzt noch eine Spalte habe, die in gleicher Weise pivotisiert und die Ergebnisse dann auch noch im Wechsel ausgegeben werden soll, steh ich ein bisschen auf dem Schlauch.

Ein Freund hat ein ähnliches Problem und er probiert gerade aus, ob das sinnvoll ist, die Ausgangs-Tabelle so wie sie ist, einzulesen und in C# dann entsprechend vor zubereiten. Das Problem an der Sache ist aber, dass am Ende ein DataReader ausgegeben werden muss, also muss er die aufbereiteten Daten wieder in eine temporäre Tabelle schreiben, die er dann wieder normal auslesen und mit einem DataReader zurück geben kann.

Kennt da vielleicht jemand eine Möglichkeit, wie wir das in SQL lösen könnten, ohne dass das Statement einen zu großen und komplizierten Umfang erhält?

Gruß

F
115 Beiträge seit 2012
vor 10 Jahren

Hi,

offenbar hat MSSQL keine Funktion dafür (wie z.B. Oracle mit LISTAGG). Ich fand eine Lösung mit XML-Path

How to simulate the MySQL group_concat function in MS SQL Server

aber vielleicht solltest Du Dir auch mal LINQ ansehen

How to: Group Query Results (C# Programming Guide)

Allerdings könnte ich mir denken, das die Straßenliste sehr lang werden kann, was zumindest dem Erzeugen einer temp-Tabelle in der DB entgegen stehen kann.

Ich würde also noch einnmal darüber nachdenken, ob eine Matrix wirklich die richtige Lösung für Euer Grundproblem ist.

Gruß
f_igy

Palladin007 Themenstarter:in
2.078 Beiträge seit 2012
vor 10 Jahren

Das war nur ein Beispiel, nicht das wirkliche Problem.
Ich habr nur versucht, es so anschaulicher zu machen.

Anders lösen können wir das aber nicht, da das ein Problem auf Arbeit ist und wir zwei versuchen dafür eine Lösung zu finden.
Und weshalb wir das wirklich in dieser Form brauchen, liegt daran, dass die Daten anschließend in einer Excel-Tabelle ausgegeben werden sollen, wo dann auch jede Id (hier jede Stadt) nur ein einziges mal vor kommt.

Daran können wir nichts ändern.

Du sagst also, MsSQL bietet keine solche Funktion an?
Dann weiß ich zumindest, dass ich nicht weiter suchen muss.

Hast du denn eine Idee, wie man das halbwegs attraktiv über andere Wege lösen könnte?
Ich würde das ungern mittels C# lösen, gerade weil die Tabelle teilweise auch sehr lang werden kann. Im Ergebnis ist das egal, aber ich mach mir ein bisschen Sorgen um die Performance, weil das ganze auch noch bei einigen Tausend Zeilen, theoretisch sogar bis zu einer Million Zeilen funktionieren muss.
Spalten können wir wahrscheinlich auf rund 100 das Maximum setzen, aber wirklich technisch darf da auch keine Grenze sein.

Deine zwei Links werde ich mir mal anschauen, gerade der Erste sieht interessant aus, danke dafür.

Edit: Scheinbar hilft der Eintrag in ANdy's Blog auch nicht. 😕

R
212 Beiträge seit 2012
vor 10 Jahren

Ich bin mir jetz nich sicher ob das so gewollt ist aber denke so könnte mann das lösen:


DECLARE @T TABLE(HEAD varchar(50), VALUE varchar(50));
DECLARE @STR1 varchar(50);
DECLARE @STR2 varchar(50);

DECLARE @I int;
SET @I = 1;
while (SELECT MAX(MyTable.Reihenfolge) FROM MyTable) < @I
BEGIN
SET @I = @I +1;
SET @STR1 = (SELECT MyTable.StraßeName FROM MyTable WHERE MyTable.Reihenfolge = @I);
SET @STR2 = (SELECT MyTable.StraßeTyp FROM MyTable WHERE MyTable.Reihenfolge = @I);
INSERT INTO @T (HEAD, VALUE)
VALUES (@STR1, @STR2 + '505');--Hier Einfach n bisschen mit dem string rumspielen
END

Die Tabelle @T könntest du dann Pivotisieren.

Palladin007 Themenstarter:in
2.078 Beiträge seit 2012
vor 10 Jahren

Sieht kompliziert aus 😄

Aber auf jeden Fall habe ich jetzt schonmal diese Arbeitsweise an sich kapiert - mehr oder weniger 😄

Dein Statement funktioniert bei mir aus irgendeinem Grund nicht, kann aber auch sein, dass ich das falsch bei mir umgesetzt habe. Ich werd mich am Montag damit nochmal auseinander setzen, vielleicht finde ich meinen Fehler dann ja auch selber.

PS:

Ne, ich kapier es einfach nicht.
Der fügt in der Schleife keine Elemente in die Tabelle ein. Ich hab auch mal Testweise eine Tabelle erstellt, die einfach nur jeden Stand des Zählers enthalten soll und auch die ist leer.

Daher habe ich gedacht, dass vielleicht aus irgendeinem Grund die MAX-Funktion 1 oder kleiner zurück gibt, wenn ich die aber gesondert ausgeben lasse um mir das Ergebnis anzuschauen, ist das größer als 1.

Ich mach jetzt aber auch Feierabend, mir raucht der Kopf. 😄

6.911 Beiträge seit 2009
vor 10 Jahren

Hallo Palladin007,

als "Notlösung" fällt mir eine selbst erstellte SQL-CLR-Function ein.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

Palladin007 Themenstarter:in
2.078 Beiträge seit 2012
vor 10 Jahren

Was sind denn SQL-CLR-Function?

Ist das sowas wie eine Funktion in C#, die ich dann im SQL-Statement aufrufen kann?
Ich dachte sowas geht nur von SQL selber aus, wenn ich dann dort eine Funktion schreibe.

Leider hab ich damit überhaupt keine Erfahrung und das Projekt ist auch nicht privat, sondern von der Arbeit. Ein Fetcher, der die Daten in einer bestimten Form auslesen soll, deshalb kann ich an der Form nichts ändern.

Warum genau ist CLR denn standardmäßig deaktiviert, was hätte das für Auswirkungen, wenn das aktiviert wird?
Ich hab nicht die Rechte um hier irgendwas groß zu ändern. Und ich möchte nicht fragen, ohne irgendwas präsentieren zu können.

Nach dem, was ich so lese, scheint mir das so, als wäre das eine extra Assambly, die dann im SQL-Server registriert wird, damit die enthaltenen Funktionen dann aufgerufen werden können.
Liege ich da richtig? Denn wenn ja, dann kann ich mir das vermutlich abschminken.

PS: Ist aber trotzdem ein schöner Hinweis, vielleicht kann ich das Privat in einem Projekt nutzen. ^^

6.911 Beiträge seit 2009
vor 10 Jahren

Hallo Palladin007,

Liege ich da richtig?

Ja - nur die CLR-Assembly wird nicht im SQL Server sondern in der jeweiligen DB registriert.

Warum genau ist CLR denn standardmäßig deaktiviert, was hätte das für Auswirkungen, wenn das aktiviert wird?

Rein aus Sicherheitsgründen ist das wohl standardmäßig aus. Aber für die CLR-Assembly gibt es Sicherheitsstufen mit denen die "Möglichkeiten" eingestellt werden können. Mit vollen Rechten kann schnell Blödsinn gemacht werden, das schreckt DB-Admins sicher ab. Aber mit den eingeschränktesten Rechten kann eigentlich nichts passieren, was nicht auch mit T-SQL möglich wäre.

Die anderen Fragen schlag bitte selbst bzw. denk ich das hast du eh bereits 😉

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

Palladin007 Themenstarter:in
2.078 Beiträge seit 2012
vor 10 Jahren

Coole Sache ... 😄

Aber ich denke, da lässt sich auf Arbeit nix machen. Fragen kann ich ja mal, aber Hoffnung hab ich da keine. 😕

Trotzdem Danke, für den Tipp, werd ich mir auf jeden Fall merken. ^^

R
212 Beiträge seit 2012
vor 10 Jahren

Wenn dien statement in die tabelle keine Daten schreibt, schfreibst du entweder keine daten in die strings, oder der INSERT ist falsch, bei fehlern in der schleife wird eig ne fehlermeldung rausgegeben.