2017-03-02 1 views
1

ich von id ersten beiden Top voted Beiträge dann andere sortiert anzeigen möchtenMysql, um von oben zwei dann id

Diese Tabelle ist

+----+-------+--------------+--------+ 
| Id | Name | Post   | Votes | 
+====+=======+==============+========+ 
| 1 | John | John's msg | -6  | 
| 2 |Joseph |Joseph's msg | 8  | 
| 3 | Ivan | Ivan's msg | 3  | 
| 4 |Natalie|Natalie's msg | 10  | 
+----+-------+--------------+--------+ 

Nach Abfrage-Ergebnis sein sollte:

+----+-------+--------------+--------+ 
    | Id | Name | Post   | Votes | 
    +====+=======+==============+========+ 
    | 4 |Natalie|Natalie's msg | 10  | 
    | 2 |Joseph |Joseph's msg | 8  | 
----------------------------------------------- 
    | 1 | John | John's msg | -6  | 
    | 3 | Ivan | Ivan's msg | 3  | 
    +----+-------+--------------+--------+ 

Ich habe 1 Lösung, aber ich habe das Gefühl, dass es einen besseren und schnelleren Weg gibt. I 2 Abfragen ausführen, ein Top-2 zu erhalten, dann zweite andere zu erhalten:

SELECT * FROM table order by Votes desc LIMIT 2 

SELECT * FROM table order by Id desc 

Und dann in PHP ich sicher, dass ich erste Abfrage zeigen, wie es ist, und 2. Abfrage entfernen i Eintrag des auf die Anzeige, dass sind in der ersten Abfrage, so dass sie nicht verdoppeln. Kann dies in Einzelabfrage getan werden, um die ersten beiden oberen gewählt wählen, dann andere?

Antwort

2

Sie müssten Unterabfragen oder Union verwenden - was bedeutet, dass Sie eine einzelne äußere Abfrage haben, die mehrere Abfragen enthält. Ich würde einfach die IDs aus der ersten Abfrage abrufen und eine ID nicht in (...) Kriterium der where-Klausel der zweiten Abfrage hinzufügen - also die in der ersten Abfrage abgerufenen Beiträge Ausfiltern:

SELECT * FROM table WHERE Id NOT IN (...) ORDER BY Id DESC 

Mit union die Abfrage würde wie folgt aussehen:

(SELECT table.*, 1 as o FROM table order by Votes desc LIMIT 2) 
UNION 
(SELECT table.*, 0 FROM table 
    WHERE Id NOT IN (SELECT Id FROM table order by Votes desc LIMIT 2)) 
ORDER BY o DESC, if(o=1,Votes,Id) DESC 

wie Sie sehen können, es wickelt 3 Abfragen in ein und hat eine kompliziertere Anordnung als auch, weil in union die Reihenfolge der abgerufenen Datensätze ist nicht garantiert.

Zwei einfache Abfragen scheinen mir in diesem speziellen Fall viel effizienter zu sein.

+0

Ich denke, dass MySQL eine LIMIT in der Unterabfrage nicht unterstützt, aber Sie können stattdessen eine Verknüpfung verwenden – fthiella

+0

@fthiella pls überprüfen Sie den Link auf Union. Es sagt sonst :) – Shadow

+0

Ja, das Problem ist nicht auf der Union-Abfrage, wo das Limit unterstützt wird, aber auf dem 'NICHT IN (wählen Sie ... LIMIT 2)' wo es nicht ist – fthiella

1

Es könnte verschiedene Möglichkeiten geben, eine Abfrage zu schreiben, die die Zeilen in der gewünschten Reihenfolge zurückgibt. Meine Lösung ist dies:

select 
    table.* 
from 
    table left join (select id from table order by votes desc limit 2) l 
    on table.id = l.id 
order by 
    case when l.id is not null then votes end desc, 
    tp.id 

die Unterabfrage die ersten beiden id Rückkehr nach Stimmenzahl ab bestellt, die kommen wird erfolgreich sein, wenn die Zeile eine der ersten beiden ist sonst l.id statt null sein wird.

Die Reihenfolge nach sortiert nach Anzahl der Abstimmungen desc, wenn die Zeile die erste oder die zweite ist (= l.id ist nicht null), wenn l.id null ist, werden die Zeilen am unteren Rand und die Reihenfolge nach geordnet ID stattdessen.

Verwandte Themen