it-swarm.com.de

Gibt Zeilen zwischen einem bestimmten Bereich mit einer select-Anweisung zurück

Ich freue mich auf einen Ausdruck wie dieser (mit SQL Server 2008)

SELECT TOP 10 columName FROM tableName

Stattdessen brauche ich die Werte zwischen 10 und 20. Und ich frage mich, ob es eine Möglichkeit gibt, dies mit nur einer SELECT-Anweisung zu tun.

Das ist zum Beispiel nutzlos:

SELECT columName FROM
(SELECT ROW_NUMBER() OVER(ORDER BY someId) AS RowNum, * FROM tableName) AS alias
WHERE RowNum BETWEEN 10 AND 20

Weil die select-Klammern bereits alle Ergebnisse zurückgeben, und ich versuche, dies aufgrund der Leistung zu vermeiden.

13
user1823901

Es gibt einen Trick mit row_number, bei dem nicht alle Zeilen sortiert werden.

Versuche dies:

SELECT columName
FROM (SELECT ROW_NUMBER() OVER(ORDER BY (select NULL as noorder)) AS RowNum, *
      FROM tableName
     ) as alias
WHERE RowNum BETWEEN 10 AND 20

Sie können keine Konstante im order by verwenden. Sie können jedoch einen Ausdruck verwenden, der eine Konstante ergibt. SQL Server erkennt dies und gibt nur die Zeilen zurück, die ordnungsgemäß aufgelistet wurden.

8
Gordon Linoff

Warum würde Ihrer Meinung nach der SQL Server die gesamte innere Abfrage auswerten? Wenn Ihre Sortierspalte indiziert ist, werden nur die ersten 20 Werte gelesen. Wenn Sie wirklich nervös sind, können Sie Folgendes tun:

Select
  Id 
From (
  Select Top 20 -- note top 20
    Row_Number() Over(Order By Id) As RowNum,
    Id 
  From
    dbo.Test
  Order By
    Id
  ) As alias
Where
  RowNum Between 10 And 20
Order By
  Id

aber ich bin mir ziemlich sicher, dass der Abfrageplan in beiden Fällen derselbe ist.

(Wirklich) Fixiert nach Aarons Kommentar.

http://sqlfiddle.com/#!3/db162/6

3
Laurence

Verwenden Sie SQL Server 2012 zum Abrufen/Überspringen! 

SELECT SalesOrderID, SalesOrderDetailID, ProductID, OrderQty, UnitPrice, LineTotal
FROM AdventureWorks2012.Sales.SalesOrderDetail
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;

Es gibt nichts Besseres, als Sie für ältere Versionen von SQL Server beschreiben. Verwenden Sie vielleicht CTE, aber es ist unwahrscheinlich, dass es einen Unterschied macht. 

WITH NumberedMyTable AS
(
    SELECT
        Id,
        Value,
        ROW_NUMBER() OVER (ORDER BY Id) AS RowNumber
    FROM
        MyTable
)
SELECT
    Id,
    Value
FROM
    NumberedMyTable
WHERE 
    RowNumber BETWEEN @From AND @To  

oder, Sie können die oberen 10 Reihen entfernen und dann die nächsten 10 Reihen erhalten, aber ich verdopple, dass jeder das tun möchte.

1
RAS

Eine weitere Option

SELECT TOP(11) columName
FROM dbo.tableName
ORDER BY
CASE WHEN ROW_NUMBER() OVER (ORDER BY someId) BETWEEN 10 AND 20 
     THEN ROW_NUMBER() OVER (ORDER BY someId) ELSE NULL END DESC
1

Sie könnten eine temporäre Tabelle erstellen, die so angeordnet ist, wie Sie möchten:

SELECT ROW_NUMBER () OVER (ORDER BY SomeId) AS RowNum, * FROM-Tabellenname In ## tempTable ...

Auf diese Weise haben Sie eine geordnete Liste von Zeilen . Sie können die nachfolgenden Zeiten einfach nach Zeilennummern abfragen, anstatt die innere Abfrage mehrmals auszuführen.

0
user3688672