2016-05-13 4 views
1

enter image description hereIch brauche das Ergebnis gemäß Angaben in SQL Server 2008

Ich habe zwei verschiedene Tabellen von gleichen Spalten zu erhalten. Einer ist # temp1 und ein anderer ist # temp2.

Die angehängten Bilder enthalten den Datensatz für jede Tabelle.

Ich habe eine Abfrage schreiben, um die Daten zu erhalten. Hier ist die Abfrage:

SELECT distinct A.EmpID, A.DeptIdID, A.RoomID, 
    IN= CASE WHEN DATEDIFF(S, A.IN, B.IN) >= 0 THEN B.IN ELSE A.In END, 
    Out= CASE WHEN DATEDIFF(S, A.Out, B.Out) >= 0 THEN A.Out ELSE B.Out END 

FROM #temp1 A 
INNER JOIN #temp2 B 
ON (A.In>= B.In AND A.In< B.In) 
    OR (A.Out> B.OutAND A.Out<= B.Out) 

Was ich will, ist, die Daten von # temp1 das zu bekommen, gehört aus zwischen der In- und Out des # temp2. Die obige Abfrage funktioniert ziemlich gut für den absoluten Ein- und Ausstieg.

Betrachten Sie den Eintrag Nr. 11 von # temp1 und den Eintrag Nr. 1 und 4 von # temp2. Die Ein- und Ausgabe von # temp1 erfolgt vom 17. April bis zum 20. April, während in # temp2 zwei Einträge für diesen Datumsbereich vorhanden sind. Der eine ist vom 12. April bis 18. April und der andere vom 18. April bis zum 20. April. Daher sollte das Ergebnis von # temp1 zwei folgende Einträge enthalten.

  1. 17. April - 18 Apr mit RoomId = 1 aus dem Spaltenwert von # temp2.
  2. 18. April - 20. April mit RoomId = 2 aus dem Spaltenwert von # temp2.

und es sollte nur eindeutige Spalte für # temp1 sein.

+1

Hier ist ein großartiger Ort zum starten. http://spaghettidba.com/2015/04/24/how-to-post-a-t-sql-question-on-a-public-forum/ –

+0

Ihre Beispiele sind sehr begrenzt. Was passiert zum Beispiel, wenn mehrere kleinere Bereiche innerhalb eines großen Bereichs in der anderen Tabelle liegen? Ihre Daten sollten als Text/Insert-Klauseln/in SQL Fiddle sein, wenn Ihnen jemand wirklich helfen möchte, anstatt Ihre Daten aus einem Bild zu schreiben. –

+0

Könnte ein interessantes Problem sein, aber es ist nicht klar, was Sie erreichen wollen oder was die Daten bedeuten. Ich nehme an, dass Empid einzigartig ist. Ist der Raum eindeutig durch deptid + roomid definiert? Stellen die beiden Tabellen Räume in zwei Abteilungen deptid = 1 und 0 dar und wer hat sie gebucht und welche Buchungsdaten haben sie genutzt? Sieht so aus, als ob die JOIN-Bedingung keine Zeilen zurückgibt, wie sie sind. –

Antwort

0

Ich mag die Frage missverstehen, aber es sieht so aus, als ob Sie Mitarbeiter finden möchten, die verschiedene Räume zu überlappenden Daten gebucht/benutzt haben. Wenn Sie #temp1 und #temp2 in eine Tabelle verketten #rooms, können Sie dies ausführen:

SELECT * 
FROM #rooms A 
INNER JOIN #rooms B on a.empid = b.empid 
    and a.deptid * 10000 + a.roomid < b.deptid * 10000 + b.roomid 
where (A.indt <= B.outdt and A.outdt >= B.indt) 

Ich gehe davon aus dem Zimmer von deptid & roomid identifiziert wird. Ich verwende einen schnellen und schmutzigen Hack, um eine einzelne ganze Zahl zu erzeugen, die die Kombination deptid und roomid eindeutig identifiziert, vorausgesetzt roomid ist immer kleiner als 10000.

Wenn roomid eindeutig den Raum identifiziert, verwenden Sie diese:

SELECT * 
FROM #rooms A 
INNER JOIN #rooms B on a.empid = b.empid 
    and a.roomid < b.roomid 
where (A.indt <= B.outdt and A.outdt >= B.indt) 

Der a.roomid < b.roomid Trick Duplikate eliminiert. Wenn Sie a.roomid <> b.roomid sagten, würde die gleiche Überlappung zweimal berichtet, einmal aus der Sicht von A und wieder aus der Sicht von B.

Ich nehme auch empid identifiziert den Mitarbeiter eindeutig. Die Mitarbeiteridentität ist tendenziell unternehmensweit, da Mitarbeiter zwischen Abteilungen wechseln können.

HTH. Es war eine interessante Frage, bitte posten Sie zurück, wenn Sie etwas anderes wollten.

+0

Ich schätze Ihre Mühe und Ihren Beitrag. Es gibt eine zusätzliche Last von 10000, die für mich nicht funktionieren wird, da es in jeder Tabelle Billionen von Datensätzen gibt. – Avtansh

0

Wenn ich verstehe, dass Sie sich dies helfen wird:

SELECT a.EmpId, 
     a.DeptId, 
     a.RoomId, 
     CASE WHEN ROW_NUMBER() OVER (PARTITION BY a.EmpId ORDER BY a.[In]) = 1 THEN a.[In] ELSE b.[In] END as [In], 
     CASE WHEN ROW_NUMBER() OVER (PARTITION BY a.EmpId ORDER BY a.[In]) = 2 THEN a.[Out] ELSE b.[In] END as [Out] 
FROM #temp1 a 
INNER JOIN #temp2 b 
    ON b.[In] between a.[In] and a.[Out] and b.[Out] between a.[In] and a.[Out] 

Ausgang:

EmpId  DeptId  RoomId  In   Out 
----------- ----------- ----------- ---------- ---------- 
7637  1   1   2016-04-17 2016-04-18 
7637  1   1   2016-04-18 2016-04-20 
7638  1   1   2016-04-15 2016-04-18 
7638  1   1   2016-04-18 2016-04-20 
7639  1   1   2016-04-17 2016-04-18 
7639  1   1   2016-04-18 2016-04-20 

Aber wenn es mehr als zwei Zeilen in #temp2 für 1 Zeile in #temp1 ist, die nicht arbeiten würde Sie.

+0

Ich schätze Ihren Einsatz und Beitrag. Aber das funktioniert nicht für mich, da es in # temp2 mehrere Zeilen für 1 Zeilen in # temp1 gibt und umgekehrt auch da ist. – Avtansh

0

Ich habe die Antworten durchgelesen und schätze die Bemühungen jedes Mitwirkenden der Stack Overflow Entwickler-Community.

Ich habe beide oben genannten Methoden angewendet, aber in meinem Fall nicht funktioniert.

Ich arbeitete an dieser Abfrage aus der letzten Woche und bekam endlich, was ich will. Hier ist es, was ich getan habe.

SELECT 
    ROW_NUMBER() OVER (ORDER BY A.EmpID, A.In, A.Out) AS RowID, 
    A.EmpID, 
    IN= CASE WHEN DATEDIFF(S, A.In, B.In) >= 0 THEN B.In ELSE A.In END, 
    Out= CASE WHEN DATEDIFF(S, A.Out, B.Out) >= 0 THEN A.Out ELSE B.Out END, 
    CASE WHEN B.DeptID=1 THEN 1 ELSE 0 END AS IsAuthorized, 
    CASE WHEN (((A.In>= B.In AND A.In <= B.Out)) AND B.DeptID=1 AND A.DeptId=1) 
     THEN 1 ELSE 0 END AS IsAccessed 

    FROM #temp1 A 
    INNER JOIN #temp2 B 
    ON A.EmpID=B.EmpID 
    AND ((A.In>= B.In AND A.In < B.Out) 
      OR (A.Out > B.In AND A.Out <= B.Out)) 
    ORDER BY A.EmpID 

Noch einmal schätze ich Ihre Bemühungen.

Glücklich Coding :)

Vielen Dank!

Avtansh