2016-11-16 2 views
2

Ich suche nach einer benutzerdefinierten Ordnungslogik durch mySQL zu ermöglichen, die den folgenden Datensatz erlaubt:Alternative, um durch eine Logik in MySQL

+----+-----------------+------------+-------+--+ 
| ID |  item  | Popularity | Views | | 
+----+-----------------+------------+-------+--+ 
| 1 | A special place |   3 | 10 | | 
| 2 | Another title |   5 | 12 | | 
| 3 | Words go here |   1 | 15 | | 
| 4 | A wonder  |   2 |  8 | | 
+----+-----------------+------------+-------+--+ 

einen Auftrag zurückzugeben, die im Wechsel, Zeile für Zeile, nach Beliebtheit und dann von Ansichten, so dass die Rückkehr Ergebnisse wie folgt aussehen:

+----+-----------------+------------+-------+--+ 
| ID |  item  | Popularity | Views | | 
+----+-----------------+------------+-------+--+ 
| 3 | Words go here |   1 | 15 | | 
| 2 | Another title |   5 | 12 | | 
| 4 | A wonder  |   2 |  8 | | 
| 1 | A special place |   3 | 10 | | 
+----+-----------------+------------+-------+--+ 

wo Sie die erste Zeile gibt die ‚beliebtesten‘ sehen, die zweite Reihe die meisten Ansichten zurück, die dritte Reihe, die zweitbeliebteste zurückgibt, und Die 4. Reihe gibt die zweithöchsten Ansichten zurück.

Momentan sammle ich eine ganze Tabelle zweimal durch mySQL und füge diese Ergebnisse dann in PHP zusammen. Dies wird es nicht schneiden, wenn die Datenbank groß ist. Ist das überhaupt in Mysql möglich?

+0

Warum möchten Sie die Zeilen so sortiert? –

+0

Ja, es ist möglich - obwohl ich Ihren aktuellen Ansatz auch mag – Strawberry

+1

Sie können diese Art der Sortierung in PHP mit 'usort' machen, nicht sicher, wie Sie es in MySQL direkt tun. –

Antwort

0

Ich denke, etwas in dieser Richtung könnte funktionieren. Beachten Sie Folgendes:

DROP TABLE IF EXISTS my_table; 

CREATE TABLE my_table 
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY 
,x INT NOT NULL 
,y INT NOT NULL 
); 

INSERT INTO my_table VALUES 
(1,3,10), 
(2,5,12), 
(3,1,15), 
(4,2, 8) 
(5,4, 1); 

Wir x und y wiederum Rang können, und dann die Reihen in einer einzigen Liste anordnen - so haben x1, y1, x2, y2, usw. - aber alle Zeilen erscheinen zweimal; einmal für den x Rang und einmal für den y Rang ...

 SELECT * FROM 
     (
     (SELECT a.*, COUNT(*) rank FROM my_table a JOIN my_table b ON b.x <= a.x GROUP BY a.id) 
      UNION ALL 
     (SELECT a.*, COUNT(*) rank FROM my_table a JOIN my_table b ON b.y <= a.y GROUP BY a.id) 
     ) n 
     ORDER BY rank 

     +----+---+----+------+ 
     | id | x | y | rank | 
     +----+---+----+------+ 
     | 5 | 4 | 1 | 1 | 
     | 3 | 1 | 15 | 1 | 
     | 4 | 2 | 8 | 2 | 
     | 4 | 2 | 8 | 2 | 
     | 1 | 3 | 10 | 3 | 
     | 1 | 3 | 10 | 3 | 
     | 5 | 4 | 1 | 4 | 
     | 2 | 5 | 12 | 4 | 
     | 2 | 5 | 12 | 5 | 
     | 3 | 1 | 15 | 5 | 
     +----+---+----+------+ 

Jetzt können wir nur für jeden id des niedrigsten Rang greifen ...

SELECT id 
    , x 
    , y 
    FROM 
    (
     (SELECT a.*, COUNT(*) rank FROM my_table a JOIN my_table b ON b.x <= a.x GROUP BY a.id) 
     UNION ALL 
     (SELECT a.*, COUNT(*) rank FROM my_table a JOIN my_table b ON b.y <= a.y GROUP BY a.id) 
    ) m 
GROUP 
    BY id,x,y 
ORDER 
    BY MIN(rank); 
+----+---+----+ 
| id | x | y | 
+----+---+----+ 
| 3 | 1 | 15 | 
| 5 | 4 | 1 | 
| 4 | 2 | 8 | 
| 1 | 3 | 10 | 
| 2 | 5 | 12 | 
+----+---+----+   

übrigens dies mit Variablen schneller sein sollte - Aber ich kann die Lösung derzeit nicht funktionieren lassen - vielleicht einen älteren Moment.

+0

Hölle ja - das sieht ziemlich gut aus. Ich werde einige Tests mit dieser Logik durchführen und das als richtig prüfen, wenn alles gut ist. Danke für Ihre Hilfe. –