2016-11-15 3 views
0

Ich versuche, alle Daten von allen Benutzern vor einem Datum/Uhrzeit, die für jeden Benutzer eindeutig ist.MySQL mehrreihige Sub-Abfrage beheben

Ich kann alle Daten für das genaue Datum für jeden Benutzer zurückgeben, kein Problem, aber ich weiß nicht, wie ich meine Abfrage erweitern kann, um Daten zurückzugeben, die kleiner oder gleich meinem Schlüsseldatum sind.

Ich habe eine SQL-Datenbank mit 2 Tabellen.

Tabelle 1 - "Verkauf" hat eine Bestätigung aller Transaktionen.

  • user_id (Datum, und dann verschiedene Kaufinformationen)

Tabelle 2 - "user_data"

  • user_id, record_date, purchase_made (purchase_made misnamed eine Aufzeichnung aller Internetdaten hat, ist , dass sie ausgelöst Kauf Popup, aber möglicherweise nicht tatsächlich einen Kauf getätigt - und dann eine ganze Reihe von Benutzeraktionsdaten)

Ich muss alle Benutzerdatensätze von Benutzern abrufen, die Käufe vor und einschließlich ihres ursprünglichen Kaufs getätigt haben.

Um den genauen Kauf Datensätze erhält ich die folgende verwenden:

SELECT * 
FROM user_data 
WHERE user_id IN (SELECT user_id FROM sales) 
AND record_date IN (SELECT min(record_date) FROM user_data WHERE purchase_made = 1 GROUP BY user_id); 

Jetzt alles, was ich wirklich will ist in der Lage sein, die zweiten „IN“ zu ändern „< =“ aber ich kann‘ t tu das mit einer Unterabfrage, die mehr als 1 Zeile zurückgibt.

Disclaimer - ich nicht schreiben, die Datenbank, ich habe keine Berechtigung, um die Datenbank zu ändern (noch würde ich die richtige Person sein zu tun)

Disclaimer 2 - Ich weiß, dass purchase_made mit wird die Ergebnisse ein wenig verschlechtern, weil nicht alle davon Käufe sind. Aufgrund der Berichterstellung kann das Datum aus der Verkaufstabelle jedoch so lange inaktiv sein, bis es tatsächlich weniger zuverlässig ist als die Verwendung des mit purchase_made verknüpften Zeitstempels (belegt durch umfangreiche Abfragevergleiche, die auf dem tatsächlichen Datensatz ausgeführt werden). Aber das Mandat von oben ist, dass es egal ist, sie werden mit "meistens" genau zufrieden sein.

Antwort

0

„Jetzt alles, was ich wirklich will ist in der Lage sein, die an zweiter Stelle zu ändern‚IN‘auf“ < =“

es also eine korrelierte Unterabfrage machen, indem die Datensätze Korrelieren wir die Notwendigkeit der Beseitigung‚IN‘und kann jetzt <=

SELECT * 
FROM user_data UD 
WHERE user_id IN (SELECT user_id FROM sales) 
    AND record_date <= (SELECT MIN(record_date) 
         FROM user_data UD2 
         WHERE UD2.purchase_made = 1 
         AND UD2.User_ID = UD.User_ID); 

ein anderer Ansatz wäre verwenden user_ID auf die Unterabfrage und statt einer Unterabfrage machen es zu einem Inline-Ansicht, die Sie auf der Benutzer-ID auf Basis beitreten hinzufügen und dann auf die Join-Kriterien die Daten zu vergleichen.

SELECT * 
FROM 
    user_data UD 
INNER JOIN 
    (SELECT MIN(record_date) mrd, User_ID 
    FROM user_data 
    WHERE purchase_made = 1 
    GROUP BY User_ID) UD2 ON UD.user_Id = UD2.user_Id 
          AND UD.record_date <= UD2.RecordDate 
WHERE 
    user_id IN (SELECT user_id FROM sales) 

halte ich würde die Klausel where Wechsel zu ...

WHERE 
    user_ID EXISTS (SELECT NULL FROM sales S WHERE S.user_ID = UD.user_ID) 

Ich vermute, Verkaufstisch größer und größer zu bekommen und IN wird in der Leistung im Laufe der Zeit verschlechtern, wo, wie existiert früh, um die Unterabfrage existieren kann, was zu eine verbesserte Leistung.

+0

Ich verstehe sehr wenig von dem, was gerade passiert ist. Aber ich denke, ich liebe es. Ich bin mir ziemlich sicher, dass das perfekt funktioniert hat und du mir einige Dinge zur Recherche gegeben hast. Danke Q! – Dulock

+0

@Dulock Fragen stellen, wenn Sie nicht verstehen. Wenn dies etwas ist, das Sie beibehalten müssen, oder wenn Sie Entwicklungsarbeit leisten, dann hilft Ihnen das Wissen über diese Art von Konzept! – xQbert

Verwandte Themen