2010-05-28 9 views
12

Ich benutze SQL Server 2005 und ich versuche, etwas wie folgt zu erreichen: Ich möchte die ersten x Zeilen und die letzten x Zeilen in der select select-Anweisung erhalten.Wählen Sie obere und untere Zeilen

SELECT TOP(5) BOTTOM(5) 

Natürlich BOTTOM existiert nicht, so brauche ich eine andere Lösung. Ich glaube, es gibt eine einfache und elegante Lösung, die ich nicht verstehe. Eine erneute Auswahl mit GROUP BY DESC ist nicht möglich.

Antwort

22

eine Vereinigung zu verwenden ist das einzige, was ich denken kann diese

select * from (select top(5) * from logins order by USERNAME ASC) a 
union 
select * from (select top(5) * from logins order by USERNAME DESC) b 
+0

Es gibt auch eine Möglichkeit zur Verwendung von Rownumber . Und du solltest rechts oben 2. – hgulyan

+1

@hgulyan: TOP (x) ist die bevorzugte Methode - es funktioniert auch mit UPDATE und DELETE, und ermöglicht Ihnen auch zu schreiben TOP (20%) oder TOP (@limit) und so weiter –

+0

Wusste das nicht obwohl. Danke für die Information. – hgulyan

8

überprüfen Sie den Link

SQL SERVER – How to Retrieve TOP and BOTTOM Rows Together using T-SQL

Sie rownumber zu verwenden Versuchen?

SELECT * 
FROM 
(SELECT *, ROW_NUMBER() OVER (Order BY columnName) as TopFive 
    ,ROW_NUMBER() OVER (Order BY columnName Desc) as BottomFive 
    FROM Table 
) 
WHERE TopFive <=5 or BottomFive <=5 

http://www.sqlservercurry.com/2009/02/select-top-n-and-bottom-n-rows-using.html

+1

dieser Code wird nicht funktionieren. 'Top5' und' Bottom5' können nicht so referenziert werden, Sie erhalten 'Msg 207, Level 16, Status 1, Zeile 4 Ungültiger Spaltenname 'TopFive' ...' Wenn Sie die 'ROW_NUMBER ...'in der WHERE Sie erhalten' Nachricht 4108, Level 15, Status 1, Zeile 1 Fensterfunktionen können nur in den SELECT oder ORDER BY Klauseln erscheinen. Sie müssen die SELECT und FROM in einer abgeleiteten Tabelle und ziehen Sie die WHERE an die äußere Abfrage, damit dies funktioniert, wie [@Paul in der zweiten Methode in seiner Antwort] (http://stackoverflow.com/questions/2927475/sql-server-select-top-and-bottom-rows/2927515#2927515)). –

+0

Bearbeitete Abfrage. Es war ein großer Fehler. – hgulyan

+1

Dies wird wie ein beinloser Hund laufen. Verwenden Sie UNION – gbn

1

Dann sind Sie aus - machen die Auswahl wieder ist die einzige Option, es sei denn, Sie in der vollständigen Ergebnismenge ziehen wollen, und dann alles, was dazwischen Wegwerfen.

ANY sql Ich denke, ist auf die gleiche Weise - für die Unterseite müssen Sie entweder zuerst wissen, wie viele Elemente Sie haben (materialisieren alles oder verwenden Sie count (*)) oder eine umgekehrte Sortierreihenfolge.

Entschuldigung, wenn das Ihnen nicht passt, aber am Ende .... die Realität ist es egal, und ich sehe keinen anderen Weg, das zu tun.

1

i Sie es mit Unterabfrage erraten zu erreichen haben nur EDITED tun

select * from table where id in ( 
      (SELECT id ORDER BY columnName LIMIT 5) OR 
      (SELECT id ORDER BY columnName DESC LIMIT 5) 
) 


select * from table where id in ( 
      (SELECT TOP(5) id ORDER BY columnName) OR 
      (SELECT TOP(5) id ORDER BY columnName DESC) 
) 

select * from table where id in ( 
      (SELECT TOP 5 id ORDER BY columnName) OR 
      (SELECT TOP 5 id ORDER BY columnName DESC) 
) 
+0

Es ist SQL-Server, also anstelle von LIMIT, müssen Sie TOP – hgulyan

+0

oohhhhhhhh thanx @hgulyan ich bearbeite es kann das hilft :) – Salil

+0

Msg 156, Ebene 15, Zustand 1, Zeile 3 Falsche Syntax in der Nähe des Schlüsselwortes 'ORDER'. –

3

Ist es eine Option für Sie, eine Union zu verwenden?

z.

select top 5 ... order by {specify columns asc} 
union 
select top 5 ... order by {specify columns desc} 
+1

Wenn Sie einen Code eingeben, * markieren * Sie die Zeilen und klicken Sie auf die Schaltfläche "Code" (101 010) auf der Editor-Symbolleiste! –

7

Ich glaube, Sie haben zwei Möglichkeiten:

SELECT TOP 5 ... 
FROM ... 
ORDER BY ... ASC 

UNION 

SELECT TOP 5 ... 
FROM ... 
ORDER BY ... DESC 

Oder, wenn Sie wissen, wie viele Elemente es in der Tabelle sind:

SELECT ... 
FROM (
    SELECT ..., ROW_NUMBER() OVER (ORDER BY ... ASC) AS intRow 
    FROM ... 
) AS T 
WHERE intRow BETWEEN 1 AND 5 OR intRow BETWEEN @Number - 5 AND @Number 
2

Keine wirkliche Unterschied zwischen diesem und die Union, die ich kenne, aber technisch ist es eine einzige Abfrage.

select t.* 
from table t 
where t.id in (select top 5 t2.id from table t2 order by MyColumn) 
    or 
    t.id in (select top 5 t2.id from table t2 order by MyColumn desc); 
0

Ich musste dies vor kurzem für eine sehr große gespeicherte Prozedur tun; wenn Ihre Abfrage ist ziemlich groß, und Sie wollen die Menge an Anfragen minimieren Sie @tempTable erklären könnte, legen Sie in diesem @tempTable dann von diesem @tempTable abfragen,

DECLARE @tempTable TABLE (columns..) 
INSERT INTO @tempTable 
VALUES (SELECT.. your query here ..) 

SELECT TOP(5) columns FROM @tempTable ORDER BY column ASC -- returns first to last 
SELECT TOP(5) columns FROM @tempTable ORDER BY column DESC -- returns last to first 
Verwandte Themen