Gibt es einen Wert, den ich in einem SELECT TOP verwenden kann, der alle Zeilen zurückgibt?

13

Ich erlaube dem Endbenutzer zu definieren, wie viele Zeilen von einer Abfrage zurückgegeben werden (SELECT TOP (@x)). Gibt es einen Wert, der eingegeben werden kann, bei dem alle Zeilen zurückgegeben werden? Oder muss ich die Abfrage dynamisch ohne TOP (@x) erstellen, wenn alle Zeilen zurückgegeben werden sollen?

Ich verwende SQL Server 2012.

Wayne E. Pfeffer
quelle
Ist es TOP ... ORDER BYetwas Wird das ORDER BYnoch benötigt, wenn Sie alle auswählen?
Martin Smith
1
Ich denke, ähm ... das wegzulassen TOPkommt nicht in Frage? Als hätten Sie es mit einer vordefinierten Abfrage zu tun und müssen sie etwas übergeben ?
corsiKa

Antworten:

17

Nun, es sieht so aus, als wäre TOP ein BIGINT, wenn Sie kein PERCENT verwenden . Das heißt, Sie könnten den Maximalwert von BIGINT übergeben ,

SELECT TOP (9223372036854775807) * FROM table1

Ich bezweifle ernsthaft, dass Sie jemals einen so großen Tisch sehen werden. Ich bin nicht sicher, welche Auswirkungen dies auf den Abfrageplan haben würde.

Kenneth Fisher
quelle
7
Angenommen, die Variable @xist ein BIGINT, dann SET @x = 0x7fffffffffffffffkönnte dies für einige klarer sein. Es ist sowieso einfacher, sich zu erinnern.
Martin Smith
@MartinSmith Ich bin ehrlich, ich werde es so oder so nachschlagen :) Ich habe das noch nie zuvor gesehen. Ist das eine implizite Konvertierung?
Kenneth Fisher
7
Nun, es ist einfacher, sich zu erinnern, wenn Sie sich nur an den Anfang erinnern 7und der Rest davon ist Fund Sie insgesamt 16 Zeichen für die 8 Bytes benötigen. Und ja, es wird implizit konvertiert, wenn es einer Variablen dieses Datentyps zugewiesen wird.
Martin Smith
@MartinSmith Ist es eine gute Praxis, sich auf die binäre Darstellung des Werts zu verlassen? In der Dokumentation wird angegeben , dass sich die binäre Darstellung eines Werts möglicherweise von Version zu Version von SQL Server ändert . Ich weiß auch nicht, ob ich die einzige Person bin, die immer durch die 0x7fffffffffffffffDarstellung des Maximalwerts von bigintin SqlServer verwirrt war. Der Grund ist, dass Sie in der binären Konstantenschreibweise von SqlServer 7fdas niedrigste Byte haben, während Sie in Sprachen wie c ++ das höchste Byte haben, um das Maximum des vorzeichenbehafteten Integraltyps zu erhalten.
i-one
3
@ich ein. Es ist äußerst unwahrscheinlich, dass sich die binäre Darstellung von Ganzzahltypen ändert. Es wäre sinnlos, wenn SQL Server bitweise Operatoren bereitstellen würde, die mit den Integer-Typen arbeiten, wenn nicht erwartet würde, dass wir uns auf ein bestimmtes Format verlassen könnten.
Martin Smith
12

Das könnte man auch überlegen

SET ROWCOUNT @x;

SELECT Foo
FROM Bar
ORDER BY Baz;

Anstatt von

SELECT TOP (@x) Foo
FROM Bar 
ORDER BY Baz;

Der Wert, auf den Sie @x setzen müssten, ist 0das Deaktivieren.

Dies gilt nicht mehr für Datenänderungsanweisungen, aber nicht mehr für SELECT.

2012 wird ein anderer Plan für den Fall erstellt, dass ROWCOUNT0 gegen einen Wert ungleich Null ist.

Wenn das ORDER BY Baznur dazu da ist, dem eine Bedeutung zu geben, TOPanstatt eine Präsentationsreihenfolge für die Ergebnisse bereitzustellen, und Sie keinen Index haben, der dies unterstützt, dann würde eine Aufteilung in zwei Abfragen in diesem 0Fall eine unnötige Sortierung vermeiden .

Martin Smith
quelle
8

Mit SELECT TOP 100 PERCENT können Fehler umgangen werden, wenn "TOP" in einer Abfrage verwendet wird.

MguerraTorres
quelle
1
Für mich erklärt das nicht wirklich den Grund, eine Funktion zu verwenden, die optimiert wird. Erwartet Crystal Reports, dass ein ORDER BY in der Ansichtsdefinition vorhanden ist?
Andriy M
Nein, Crystal Reports hat Probleme, Abfragen zu erfassen und eigene Ausführungspläne zu erzwingen, was sie sehr ineffizient und manchmal ungenau macht. Ich bevorzuge es, ALLE meine Logik und mein Design in der SQL-Abfrage auszuführen und sie in Crystal einfach "hübsch" zu machen. Aus diesem Grund habe ich größtenteils auf SSIS / SSRS migriert, aber es gibt immer noch Legacy-Berichte.
MguerraTorres
-2
select top(SELECT COUNT(*) FROM YourTable) * From YourTable
Abhilash Medi
quelle
1
Die Frage betrifft die Parametrisierung der TOP-Klausel. Das OP hat dort bereits einen Parameter ( @x) und fragt nun, an welchen Wert übergeben werden soll, @xdamit "alle Zeilen" angezeigt werden, unabhängig davon, wie viele Zeilen die Tabelle tatsächlich enthält. Vielleicht könnten Sie herausfinden, wie Sie Ihre Lösung an die Anforderungen des OP anpassen können.
Andriy M
1
Ich habe die Anpassungen vorgenommen, um der Frage zu entsprechen, obwohl dies, wie geschrieben, eine Race-Bedingung hat, wenn Zeilen gleichzeitig eingefügt werden. Dies würde eine Tabellensperre für die Dauer erfordern, um zu beheben, dass gleichzeitige Einfügungen blockiert werden. Dies und der zusätzliche Aufwand für das erstmalige Einchecken können vermieden werden, wenn nur eine große Anzahl verwendet wird.
Martin Smith
(SELECT COUNT(*) FROM YourTable)ist kein Wert.
Ypercubeᵀᴹ