2012-09-06 3 views
5

Ich habe Hunderttausende von Preispunkten aus über 40 Jahren. Ich möchte eine Abfrage erstellen, die nur 3000 Gesamtdatenpunkte zurückgibt, wobei die letzten 500 die neuesten Datenpunkte sind und die anderen 2500 nur eine Stichprobe der übrigen Daten sind, die gleichmäßig verteilt sind.Wählen Sie einen Teil der umfangreichen Daten im Laufe der Zeit mit MySQL

Ist es möglich, dies in einer Abfrage zu tun? Wie würde ich nur eine Stichprobe der großen Datenmenge auswählen? Dies ist ein kleines Beispiel dafür, was ich meine, für nur eine Probe der anderen 2500 Datenpunkte bekommen:

1 
2 
3  
4 
5 
6 
7 
8 
9 
10 

Und ich möchte etwas wie folgt zurück:

1 
5 
10 

Hier ist die Abfrage für die letzte 500:

SELECT * FROM price ORDER BY time_for DESC LIMIT 500 

Ich bin mir nicht sicher, wie man die Beispieldaten von den anderen Datenpunkten holt.

+0

Können Sie das Design der Tabelle zeigen? Und wie viele Datensätze hast du? – Nin

Antwort

5

starten:

(SELECT * FROM price ORDER BY time_for DESC LIMIT 500) 
UNION ALL 
(SELECT * FROM price WHERE time_for < (SELECT time_for FROM price ORDER BY time_for LIMIT 500, 1) ORDER BY rand() LIMIT 2500) 
ORDER BY time_for 

Hinweis: Es ist wahrscheinlich langsam sein würde. Wie groß ist dieser Tisch?

Es ist möglicherweise schneller, nur die primäre ID von allen diesen Zeilen zu erhalten und sie dann in einer sekundären Abfrage dem Original hinzuzufügen, sobald sie eingegrenzt ist. Dies liegt daran, dass ORDER BY rand() LIMIT die gesamte Tabelle sortieren muss. Wenn die Tabelle groß ist, kann dies eine LANGE Zeit und viel Speicherplatz beanspruchen. Nur das Abrufen der ID verringert den erforderlichen Speicherplatz.

3

Die vorherige Antwort ist gut, aber Sie haben angegeben, dass die Ergebnisse gleichmäßig verteilt werden sollen, also werde ich diese Möglichkeit auch hinzufügen. Indem Sie einen Zähler über die Zeilen iterieren, können Sie einen MOD-Operator verwenden, um eine gleichmäßige Verteilung zu ermitteln. Ich habe gerade keine MySQL-Installation, um dies zu testen, also Entschuldigungen, wenn die Syntax nicht 100% Spot ist. Aber es sollte nah genug sein und Ihnen vielleicht ein paar Ideen geben.

( SELECT p1.* 
     FROM price p1 
    ORDER BY p1.time_for DESC 
     LIMIT 500 ) 

    UNION ALL 

    ( SELECT @i := @i + 1 AS row_num, 
      p2.* 
     FROM price p2, 
      (SELECT @i: = 0) 
     WHERE row_num > 500 
     AND (row_num % 500) = 0 
    ORDER BY time_for DESC ) 

Die erste Abfrage gibt die 500 letzten Zeilen. Die zweite Abfrage gibt danach jede 500. Zeile aus und gibt somit eine gleichmäßige Verteilung von den übrigen Daten zurück. Natürlich können Sie diesen Parameter einstellen, um den gewünschten Probenabstand zu erreichen. Oder basieren Sie auf der Gesamtzahl der Zeilen in der Tabelle, um den erforderlichen Abstand zu berechnen, um genau 2500 Datensätze zu erhalten.

Verwandte Themen