Edit 1 (Erklärung): Vielen Dank für die Antworten bis jetzt! Die Antwort ist erfreulich.
Ich möchte die Frage ein wenig klären, weil ich basierend auf den Antworten einen Aspekt des Problems nicht korrekt beschrieben habe (und ich bin mir sicher, dass das meine Schuld ist, da ich Schwierigkeiten hatte, es selbst für mich zu definieren).
Hier ist der Haken: Die Ergebnismenge sollte NUR die Datensätze mit TSTAMP BETWEEN "2010-01-03" UND "2010-01-09" UND einen Datensatz enthalten, wo der Tstamp NULL für jede Bestellnummer in der ersten ist set (es wird immer mit null tstamp für jede order_num sein).
Die bisher gegebenen Antworten scheinen alle Datensätze für eine bestimmte order_num, wenn es any mit tstamp BETWEEN '2010-01-03' UND '2010-01-09'. Wenn zum Beispiel ein anderer Datensatz mit order_num = 2 und tstamp = 2010-01-12 00:00:00 vorhanden ist, sollte nicht im Ergebnis enthalten sein.Effizienter SQL als mit "A UNION (B in A)"?
Original Frage:
Betrachten Sie eine Auftragstabelle enthält ID (eindeutige), order_num, tstamp (ein Zeitstempel) und ITEM_ID (die einzelnen Artikel in einer Bestellung enthalten). Tstamp ist Null, es sei denn, die Reihenfolge wurde geändert. In diesem Fall gibt es einen anderen Datensatz mit identischer Bestellnummer und Tstamp enthält dann den Zeitstempel der Änderung.
Beispiel ...
id order_num tstamp item_id __ _________ ___________________ _______ 0 1 100 1 2 101 2 2 2010-01-05 12:34:56 102 3 3 113 4 4 124 5 5 135 6 5 2010-01-07 01:23:45 136 7 5 2010-01-07 02:46:00 137 8 6 100 9 6 2010-01-13 08:33:55 105
Was ist die effizienteste SQL-Anweisung alle Aufträge abgerufen werden (basierend auf order_num), die während eines bestimmten Zeitraums ein oder mehrmals geändert wurden? Mit anderen Worten, für jede Reihenfolge benötigen wir alle Datensätze mit der gleichen Ordnungsnummer (einschließlich der mit NULL Tstamp), für jede Ordnungsnummer WHERE mindestens eine der Ordnungsnummern hat Tstamp NOT NULL und Tstamp BETWEEN '2010-01-03' UND '2010-01-09'. Es ist die "WHERE mindestens einer der OrderNum hat Tstamp NOT NULL", mit denen ich Schwierigkeiten habe.
Die Ergebnismenge soll wie folgt aussehen:
id order_num tstamp item_id __ _________ ___________________ _______ 1 2 101 2 2 2010-01-05 12:34:56 102 5 5 135 6 5 2010-01-07 01:23:45 136 7 5 2010-01-07 02:46:00 137
Die SQL, die ich herauskommen, ist dies, die im Wesentlichen „A UNION (B in A)“, aber es führt langsam und ich hoffe, es ist eine effizientere Lösung:
SELECT history_orders.order_id, history_orders.tstamp, history_orders.item_id FROM (SELECT orders.order_id, orders.tstamp, orders.item_id FROM orders WHERE orders.tstamp BETWEEN '2010-01-03' AND '2010-01-09') AS history_orders UNION SELECT current_orders.order_id, current_orders.tstamp, current_orders.item_id FROM (SELECT orders.order_id, orders.tstamp, orders.item_id FROM orders WHERE orders.tstamp IS NULL) AS current_orders WHERE current_orders.order_id IN (SELECT orders.order_id FROM orders WHERE orders.tstamp BETWEEN '2010-01-03' AND '2010-01-09');
Ich bin neugierig auf die Leistung der bereitgestellten Abfragen, vielleicht könnten Sie Testergebnisse teilen? –
Ich werde in Kürze über die Leistungsverbesserung der endgültigen Lösung berichten - es ist signifikant. – machinatus