Laden...

2 DataTable zusammen führen

Erstellt von rohu2007 vor 6 Jahren Letzter Beitrag vor 6 Jahren 2.102 Views
R
rohu2007 Themenstarter:in
11 Beiträge seit 2017
vor 6 Jahren
2 DataTable zusammen führen

Hallo Zusammen,

ich habe ein Problem.
Ich habe 2 DataTables, die mit einem SQL Query gefüllt werden.

Die beiden DataTables haben gleiche Spalten (ProjektID, Datum), jedoch ist in der Spalte Datum der DataTable2 ein anderer wert drin als in der DataTable1

Die ProjektID in beiden DataTables ist gleich.

nun möchte ich in eine dritte DataTable die DataTable1 und DataTable2 zusammenführen, damit in der dritten Tabelle die ProjektID, Datum von Tabelle1, Datum von Tabelle2, abhängig von der ProjektID drin stehen.

ich komme einfach nicht drauf, wie ich das machen könnte 😦

Vielleicht hat aber auch jemand eine Idee, wie ich die Daten anders per SELECT aus der Datenbank bekomme.

Die Daten in der DB sehen so aus:
ProjektID | Datum | Status
10000 | 2017-12-09 | 3
10000 | 2017-12-20 | 5

Im Prinzip brauche ich das Datum vom Status 3 und Status 5 in einer Reihe:
ProjektID | DatumStatus3 | DatumStatus5
10000 | 2017-12-09 | 2017-12-20

damit muss ich später eine Differenz zwischen Datum3 und Datum5 in Tagen berechnen.

Ich hoffe, ich konnte als Leihe reichlich Infos liefern.

Für eure Hilfe danke ich jetzt schon im Voraus.

16.806 Beiträge seit 2008
vor 6 Jahren

Laut Dokumentation hat DataTable eine Merge Methode. Ist diese nicht passend für Dich - oder hast nicht in die Doku geschaut?
Wenn nicht, dann musst Du halt über die Einträge iterien und über die Key-Relationen selbst die dritte DataTable bauen.

Oder halt über ein entsprechenden JOIN im SELECT direkt alles auf einmal in der Datenbank ausführen.

R
rohu2007 Themenstarter:in
11 Beiträge seit 2017
vor 6 Jahren

Hallo und danke für deine Antwort.

Die Merge Methode ist in dem Fall leider nicht das richtige.
Bei Merge wird die zweite Tabelle an die erste angehängt.

Das mit dem JOIN im SELECT würde ich ja gern machen, nur weiß ich leider nicht wie ich das machen soll, da die Quell-Tabelle in der SQL Datenbank die selbe ist.

Könntest du mir da eventuell einen Ansatz Code Schnipsel zeigen?

Ich bin leider sehr frisch und unerfahren auf diesem Gebiet.

H
523 Beiträge seit 2008
vor 6 Jahren

Wenn dem ganzen noch eine separate Projekt-Tabelle zugrunde liegt, könnte man es wie folgt lösen:


SELECT 	projekttabelle.projektid, status3.datum as datumstatus3, status5.datum as datumstatus5
FROM	projekttabelle
LEFT JOIN statustabelle status3 ON projekttabelle.projektid = status3.projektid AND status3.status = 3
LEFT JOIN statustabelle status5 ON projekttabelle.projektid = status5.projektid AND status5.status = 5

R
rohu2007 Themenstarter:in
11 Beiträge seit 2017
vor 6 Jahren

Hallo.

Also, es gibt nur eine Tabelle, die WSProjekte heißt, in der Tabelle sind unter anderem die Spalten ProjektID, Datum und Status.

Leider ist das Datum für Status 3 oder 5 immer in der selben Spalte.

Daher habe ich auch den Knoten im Kopf, wie ich die Werte mit einer SELECT Abfrage für Status 3 und Status 5 auslesen kann.

Und auch der Status 3 und 5 sind in der selben Spalte "Status"

Hier mal die SQL Abfragen, wo ich in der selben Tabelle verschiedene Daten abfrage:


SqlDataAdapter sdaAUF = new SqlDataAdapter(@"
            SELECT DISTINCT WSAuftragNotiz.ProjektId, WSAuftragNotiz.Datum FROM WSAuftragNotiz, WSAuftrag WHERE WSAuftragNotiz.Kategorie = '3' AND WSAuftrag.Art = 20 AND WSAuftrag.ProjektId = WSAuftragNotiz.ProjektId AND (WSAuftrag.StatusId = 17 OR WSAuftrag.StatusId = 3 OR WSAuftrag.StatusId = 4)
            ", conE.ActivConE());
            DataTable dtAUF = new DataTable();
            sdaAUF.Fill(dtAUF);

            SqlDataAdapter sdaAB = new SqlDataAdapter(@"
            SELECT DISTINCT WSAuftragNotiz.ProjektId, WSAuftragNotiz.Datum FROM WSAuftragNotiz, WSAuftrag WHERE WSAuftragNotiz.Kategorie = '5' AND WSAuftrag.Art = 20 AND WSAuftrag.ProjektId = WSAuftragNotiz.ProjektId AND (WSAuftrag.StatusId = 17 OR WSAuftrag.StatusId = 3 OR WSAuftrag.StatusId = 4)
            ", conE.ActivConE());
            DataTable dtAB = new DataTable();
            sdaAB.Fill(dtAB);

H
523 Beiträge seit 2008
vor 6 Jahren

Also, es gibt nur eine Tabelle, die WSProjekte heißt, in der Tabelle sind unter anderem die Spalten ProjektID, Datum und Status.

Ausgehend davon (Achtung geraten), dass die ProjektID in der Tabelle WSAuftrag gebildet wird, könnte man das ganze wie folgt lösen:


SELECT 	WSAuftrag.projektid, status3.datum as datumstatus3, status5.datum as datumstatus5
FROM	WSAuftrag
LEFT JOIN WSProjekte as status3 ON WSAuftrag.projektid = status3.projektid AND status3.status = 3
LEFT JOIN WSProjekte as status5 ON WSAuftrag.projektid = status5.projektid AND status5.status = 5

T
111 Beiträge seit 2005
vor 6 Jahren

Hallo

Du kannst folgendes Select ausführen:


select distinct
	ProjektID
,Datum3 = (select a.Datum from Test a WHERE a.Status = 3)
,Datum5 = (select b.Datum from Test b WHERE b.Status = 5)
from Test

dann solltest Du eine Tabelle mit den gewünschten Spalten bekommen.

Thomas

P.S.
Ich habe gerade festgestellt, dass obige Lösung nicht richtig funktioniert, sorry. Die Auswertung von hypersurf liefert Dir fast die richtige Lösung, es fehlt nur ein DISTINCT im Select.

R
rohu2007 Themenstarter:in
11 Beiträge seit 2017
vor 6 Jahren

Hallo Zusammen.

Ich glaube, ich habe die ganze Sache etwas undeutlich beschrieben und es führt zu Missverständnissen.

Ich versuche es nochmal:

Ich habe nur EINE Tabelle in der aus der ich die Spalten ProjektID, Datum benötige.
Das Datum wird in der Selben Spalte gespeichert.
Abhängig vom Status der Kategorie, steht dort immer ein anderer Wert drin.

Ich füge mal einen Screenshot bei.

Weil das Datum immer in der selben Spalte steht und auch der Kategorie Status, habe ich das bisher mit 2 Abfragen gemacht um ein mal das Datum für Status 3 und ein mal das Datum für Status 5 zu bekommen.

Status 3:

SELECT DISTINCT WSAuftragNotiz.ProjektId, WSAuftragNotiz.Datum FROM WSAuftragNotiz, WSAuftrag WHERE [B]WSAuftragNotiz.Kategorie = '3'[/B] AND WSAuftrag.Art = 20 AND WSAuftrag.ProjektId = WSAuftragNotiz.ProjektId AND (WSAuftrag.StatusId = 17 OR WSAuftrag.StatusId = 3 OR WSAuftrag.StatusId = 4)

Status 5:

SELECT DISTINCT WSAuftragNotiz.ProjektId, WSAuftragNotiz.Datum FROM WSAuftragNotiz, WSAuftrag WHERE [B]WSAuftragNotiz.Kategorie = '5'[/B] AND WSAuftrag.Art = 20 AND WSAuftrag.ProjektId = WSAuftragNotiz.ProjektId AND (WSAuftrag.StatusId = 17 OR WSAuftrag.StatusId = 3 OR WSAuftrag.StatusId = 4)

Das ganze habe ich in jeweils eine DataTable geschrieben.

Es wäre natürlich viel schneller wenn ich beide Datumsangaben, für Status 3 und 5 neben einander, zur jeweiligen ProjektID hätte.

Oder wenn es eine Möglichkeit gibt, die 2 DataTables mit einer oder 2 Schleifen zu durchlaufen und diese in eine dritte DataTable richtig zu schreiben.

Tut mir leid, wenn ich für Verwirrung gesorgt habe.

Robert

3.003 Beiträge seit 2006
vor 6 Jahren

SQL ist deklarativ: "Gib mir alle Daten x, y, die folgende Bedingung erfüllen..."


SELECT note.ProjektId, note.Datum, note.Kategorie 
FROM WSAuftragNotiz note
    INNER JOIN WSAuftrag order ON (order.ProjektId = note.ProjektId AND order.Art = 20) 

WHERE 
    note.Kategorie IN ('3', '5')  AND 
   (order.StatusId IN (3, 4, 17)

(Ohne Gewähr, aber in der Art.)

LaTino
EDIT: bei einem inner join macht's mehr Sinn, von der "führenden" Tabelle auszugehen, also "SELECT x FROM order inner join note", aber sei's drum.

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

R
rohu2007 Themenstarter:in
11 Beiträge seit 2017
vor 6 Jahren

Danke für deinen Vorschlag, den ich auch verstanden habe.
Aber, das Datum von Status 3 und Status 5 bleibt immer noch in einer Spalte.

Genau das ist unbrauchbar für mich. Ich muss das Datum von Status 3 und Status 5 in separaten Spalten, nebeneinander haben.

Das ist mein Problem...

Robert

H
523 Beiträge seit 2008
vor 6 Jahren

Genau das ist unbrauchbar für mich. Ich muss das Datum von Status 3 und Status 5 in separaten Spalten, nebeneinander haben.

Warum musst Du das haben? Du kannst den Code auch so anpassen, dass Du es nicht so haben musst.

Das folgende Statement geht davon aus, dass immer ein Statuseintrag mit dem Status 3 vorhanden ist, aber nicht zwingend ein Statuseintrag mit dem Status 5. Beide Werte werden in einer Zeile ausgegeben. Duplikate musst Du selber mittels GroupBy/Distinct/Unique entfernen.


SELECT 	status3.projektid, status3.datum as datumstatus3, status5.datum as datumstatus5
FROM	WSProjekte status3
LEFT JOIN WSProjekte status5 ON status3.projektid = status5.projektid AND status5.status = 5
WHERE 	status3.projektid AND status3.status = 3

3.003 Beiträge seit 2006
vor 6 Jahren

Danke für deinen Vorschlag, den ich auch verstanden habe.
Aber, das Datum von Status 3 und Status 5 bleibt immer noch in einer Spalte.

Genau das ist unbrauchbar für mich. Ich muss das Datum von Status 3 und Status 5 in separaten Spalten, nebeneinander haben.

Das ist mein Problem...

Robert

Hatte ich wohl überlesen. Self-join löst dieses Problem.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

R
rohu2007 Themenstarter:in
11 Beiträge seit 2017
vor 6 Jahren

Hallo LaTino.

kannst du mir in etwa zeigen wie ein SELF JOIN aussehen könnte?

Das heisst, man greift auf die selbe Tabelle wieder zu, aus der man die Daten SELECTED?

R
rohu2007 Themenstarter:in
11 Beiträge seit 2017
vor 6 Jahren

Jetzt habe ich es verstanden, danke für eure Tipps und Hinweise.

So sieht die Abfrage nun aus:

SELECT a.ProjektId, a.Datum AS DatumAUF, b.ProjektId, b.Datum AS DatumAB, a.Kategorie, b.Kategorie
  FROM WSAuftragNotiz a, WSAuftragNotiz b
  WHERE a.ProjektId = b.ProjektId AND a.Kategorie = 3 AND b.Kategorie = 5
  ORDER BY a.ProjektId