2016-09-16 16 views
0

Ich habe eine Produktbestandsliste (siehe unten). Jedes Mal, wenn die Bestandsmenge eines Produkts geändert wird, wird eine Zeile mit der aktuellen Bestandsmenge zur Tabelle hinzugefügt. SoSo erhalten Sie die letzten geänderten Zeilen aus dem Produktinventar

...

  • Wie kann ich wissen, wie viel und welche Produkte im Inventar zu der angegebenen Zeit war?
  • Ist es möglich, dies mit einer Abfrage zu wissen?
  • Wie wäre es ohne Joins oder Unterabfragen?

Log Tabelle:

row_id quantity time    product_id 
2413407 1   2016-09-16 13:16:48 122559 
2413408 3696  2016-09-16 20:46:42 121152 
2413409 3697  2016-09-16 20:46:45 121152 
2413410 786   2016-09-16 20:46:47 121152 
2413411 3   2016-09-16 20:53:19 128034 
2413412 1   2016-09-16 20:53:20 143362 
2413413 2   2016-09-16 20:53:30 128051 

Zum Beispiel mit Zeitstempel 2016.09.16 20.46.46 Ich mag würde diese Zeilen raus (weil dies die genaue Bestandsaufnahme in diesem Moment war) :

row_id quantity time    product_id 
2413407 1   2016-09-16 13:16:48 122559 
2413409 3697  2016-09-16 20:46:45 121152 

Antwort

2

Sie werden Unterabfragen oder Joins benötigen. Hier ist eine Möglichkeit:

select l.* 
from log l 
where l.time = (select max(l2.time) 
       from log l2 
       where l2.product_id = l.product_id and 
         l2.time <= '2016-09-16 20:46:46' 
       ); 

Ich hätte das nicht sagen sollen. Es ist zumindest eine Möglichkeit, dies zu erhalten, ohne join oder Subqueries:

select product_id, 
     substring_index(group_concat(row_id order by time desc), ',', 1) as row_id, 
     substring_index(group_concat(quantity order by time desc), ',', 1) as quantity, 
     max(time) 
from log l 
where l.time <= '2016-09-16 20:46:46' 
group by product_id; 

Diese Methode etwas gefährlich ist, weil der Zwischen group_concat() Zeichenfolge zu 1.024 Bytes begrenzt ist. Dies ist eine Sitzungseinstellung, die leicht geändert werden kann. Außerdem werden dadurch die anderen Spalten (quantity und row_id) in Strings umgewandelt.

Schließlich denke ich, die ursprüngliche Version ist schneller mit dem richtigen Index log(product_id, time). Aber es ist möglich, Ihre Bedingungen zu erfüllen.

+0

: D Ja, ich versuche, die leistungsstärkste Version zu bekommen. Vielleicht sollte ich einfach deine erste Version verwenden. Ich habe vielleicht über etwas wie "row_number() über partition()" nachgedacht, aber das gibt es in mysql nicht, nehme ich an. – viljun

+0

@viljun. . . Wenn Sie dies mit 'row_number()' tun möchten, benötigen Sie immer noch eine Unterabfrage oder CTE. –

Verwandte Themen