T-Sql Select * Zwischen 30% und 40%

Frage

  • Wie schreibe ich eine T-SQL-gespeicherte Prozedur, mit der ich Prozentsätze von Zeilen zwischen X% und Y% auswählen kann?
  • Also im Grunde möchte ich die Zeilen zwischen 30 PERCENT und 40 PERCENT wählen …..

Ich weiß, dass du folgendes tun kannst, aber offensichtlich lässt das nicht ein Satz von Zeilen zwischen 2 Prozentsätzen angeben.

SELECT TOP 50 PERCENT * FROM tblAssets 

Hilfe sehr geschätzt.

Aktualisierte Antwort

 declare @NumRecords int SELECT @NumRecords = COUNT(*) FROM tblAssets; With Vals As ( SELECT tblAssets.AssetId ... , ROW_NUMBER() OVER ( order by tblAssets.AssetId) as RN FROM tblAssets ) SELECT tblAssets.AssetId ... FROM vals Where RN between 0.3*@NumRecords and 0.4*@NumRecords 

Ich habe meine Antwort aktualisiert, da es 2 Probleme mit meiner ursprünglichen Antwort unten gab

  1. performance – es wurde von der verschachtelten TOP Lösung geschlagen
  2. Genauigkeit – Es gibt einen unerwarteten Aspekt von NTILE, dem ich nicht bewusst war

Wenn die Anzahl der Zeilen in einer Partition nicht durch integer_expression teilbar ist, wird dies zu Gruppen von zwei Größen führen, die sich um ein Mitglied unterscheiden. Größere Gruppen kommen vor kleineren Gruppen in der Reihenfolge, die durch die OVER-Klausel angegeben ist. Wenn zum Beispiel die Gesamtzahl der Zeilen 53 ist und die Anzahl der Gruppen fünf ist, haben die ersten drei Gruppen 11 Zeilen und die beiden übrigen Gruppen haben jeweils 10 Zeilen.

Ich habe folgende Werte im Vergleich zur verschachtelten TOP Lösung.

 SET STATISTICS IO ON SET STATISTICS TIME ON; DECLARE @NumRecords int SELECT @NumRecords = COUNT(*) FROM [master].[dbo].[spt_values]; WITH Vals As ( SELECT [number] , ROW_NUMBER() OVER ( order by [number]) as RN FROM [master].[dbo].[spt_values] ) SELECT [number] FROM vals Where RN BETWEEN 0.30*@NumRecords AND 0.40*@NumRecords 

Gibt

Tabelle 'spt_values'. Scan-Zähler 1, logisch liest 8, physikalische liest 0, read-ahead liest 0, lob logisch liest 0, lob physikalische liest 0, lob read-ahead liest 0.

Tabelle 'spt_values'. Scan-Zähler 1, logisch liest 5, physikalische liest 0, read-ahead liest 0, lob logisch liest 0, lob physikalische liest 0, lob read-ahead liest 0.

 SELECT TOP 25 PERCENT [number] FROM ( SELECT TOP 40 PERCENT [number] FROM [master].[dbo].[spt_values] ORDER BY [number] ASC ) TOP40 ORDER BY [number] DESC 

Gibt

Tabelle 'Arbeitstisch'. Scan-Zähler 1, logische liest 4726, physikalische liest 0, read-ahead liest 0, lob logisch liest 0, lob physikalische liest 0, lob read-ahead liest 0.

Tabelle 'spt_values'. Scan-Zähler 1, logisch liest 8, physikalische liest 0, read-ahead liest 0, lob logisch liest 0, lob physikalische liest 0, lob read-ahead liest 0.

Ursprüngliche Antwort

 With Vals As ( SELECT tblAssets.AssetId ... , NTILE (100) OVER ( order by tblAssets.AssetId) as Pct FROM tblAssets ) SELECT * FROM vals Where Pct between 30 and 40 

Ich kam mit mir selbst …….

 SELECT TOP 40 * INTO #TOP40 FROM CCDtblAssets SELECT * FROM #TOP40 WHERE ASSETID NOT IN (SELECT TOP 30 ASSETID FROM #TOP40) 

Obwohl ich mag Martins Antwort.