2016-11-07 4 views
1

ich links müssen zwei Tabellen mit einem Join in dem Zustand:Postgres LEFT JOIN mit dem Zustand

time_table
id  rid  start_date    end_date 
1  2  2017-07-01 00:00:00  2018-11-01 00:00:00 
2  5  2017-01-01 00:00:00  2017-06-01 00:00:00 
3  2  2018-07-01 00:00:00  2020-11-01 00:00:00 
record_table
id  name     date 
1  record1  2017-10-01 00:00:00 
2  record2  2017-02-01 00:00:00 
3  record3  2017-10-01 00:00:00 

Ich brauche alle diese Datensätze zu erhalten, die unter bestimmten Zeitpunkt vorliegen Angebot. Im obigen Beispiel brauche ich die Datensätze, die nur unter rid = 2 liegen. Daraus ergibt sich die Ausgabe für die obige Abfrage muss sein:

1  record1  2017-10-01 00:00:00  
3  record3  2017-10-01 00:00:00 
+1

Was haben Sie versucht? Bitte posten Sie einen Beispielcode und geben Sie an, was nicht für Sie funktioniert. Überprüfen Sie auch diesen Link: stackoverflow.com/help/mcve. – CGritton

+1

verwenden Sie postgresql oder mysql? – chresse

+0

Ihr Ausgabebeispiel erfordert keinen äußeren Join wie im Titel der Frage. Es ist eine innere Verbindung. –

Antwort

1

LEFT JOIN zwei Tabellen mit einer where Bedingung

a Es ist Falle für Sie warten hier. Wenn Sie LEFT [OUTER] JOIN verwenden, ist es in der Regel falsch zu filtern mit einer WHERE Bedingung, wodurch das spezielle Feature einer LEFT JOIN, alle Zeilen aus der linken Tabelle bedingungslos. Ausführliche Erläuterung:

So setzen Bedingungen in die WHERE Klausel, die alle Zeilen filtern sollen (rid = 2), aber die Bedingungen machen links beitreten Reihen von record_table sich als tatsächliche beitreten Bedingungen:

SELECT t.start_date, t.end_date -- adding those 
    , r.id, r.name, r.date 
FROM time_table t 
LEFT JOIN record_table r ON r.date >= t.start_date 
          AND r.date < t.end_date 
WHERE t.rid = 2; 

As commented, macht es Sinn, von time_table in den Ergebnisspalten enthält, aber das ist mein optional addit Ion.

Sie müssen auch sehr klar über oberen und unteren Grenzen sein. Die allgemeine Konvention ist enthalten unteren und auszuschließen die obere Grenze in der Zeit (timestamp) reicht. Daher meine Verwendung von >= und < oben.

Verwandte:

Leistung kein Problem bei allen mit dem richtigen Indizes sein sollte. Sie benötigen einen Index (oder PK) unter time_table unter (rid) und einen weiteren unter record_table unter (date).

1
SELECT time_tbl.name,record_tbl.date 
FROM dbo.time_table AS time_tbl 
    INNER JOIN record_table AS record_tbl 
      ON time_tbl.id=record_tbl.id 
WHERE(time_tbl.rid=2)  
+4

Dies ist in fast jeder Hinsicht falsch. Falscher JOIN, falscher Zustand, falsche Ergebnisspalten. Das kann passieren, aber vor allem: überhaupt keine Erklärung. –

0

Ich bin mir nicht ganz sicher, ob dies ist, was Sie wollen, aber wenn Sie sagen möchten, dass Sie die Daten, wo das record_table Datum zwischen dem ist Termine im time_table, würde dann dies die Arbeit machen:

select 
    rt.id, rt.name, rt.date 
from 
    time_table tt 
    join record_table rt on 
    rt.date between tt.start_date and tt.end_date 
where 
    tt.rid = 2 

das heißt, wird dies für große Datensätze schrecklich ineffizient sein. Wenn Ihre Daten relativ klein sind (< 10k Datensätze in jeder Tabelle, Post-Filter), dann wird es wahrscheinlich nicht viel ausmachen, aber wenn Sie dieses Konzept skalieren müssten, würde es ausreichen, mehr über Ihre Daten zu wissen - zum Beispiel , machen die Daten immer zum ersten jeden Monats?

Nochmals, von Ihrem Beispiel war ich nicht sicher, ob Sie das mit "alle Datensätze, die unter einem bestimmten Datumsbereich vorhanden sind" gemeint haben.