Jawaban:
SELECT
columns
FROM
(
SELECT TOP 200
columns
FROM
My_Table
ORDER BY
a_column DESC
) SQ
ORDER BY
a_column ASC
Itu tidak perlu. Anda dapat menggunakan ORDER BY
dan hanya mengubah pengurutan DESC
untuk mendapatkan efek yang sama.
Maaf, tapi menurut saya saya tidak melihat jawaban yang benar menurut pendapat saya.
Fungsi TOP
x menunjukkan catatan dalam urutan yang tidak ditentukan. Dari definisi tersebut BOTTOM
dapat disimpulkan bahwa suatu fungsi tidak dapat didefinisikan.
Independen indeks atau urutan apa pun. Ketika Anda melakukannya, ORDER BY y DESC
Anda mendapatkan baris dengan nilai y tertinggi terlebih dahulu. Jika ini adalah ID yang dibuat secara otomatis, itu harus menunjukkan catatan yang terakhir ditambahkan ke tabel, seperti yang disarankan dalam jawaban lain. Namun:
TOP
fungsinyaJawaban yang benar adalah bahwa tidak ada, dan tidak mungkin, setara dengan TOP
mendapatkan baris terbawah.
Secara logis,
BOTTOM (x) is all the records except TOP (n - x), where n is the count; x <= n
Misalnya Pilih 1000 Terbawah dari Karyawan:
Di T-SQL,
DECLARE
@bottom int,
@count int
SET @bottom = 1000
SET @count = (select COUNT(*) from Employee)
select * from Employee emp where emp.EmployeeID not in
(
SELECT TOP (@count-@bottom) Employee.EmployeeID FROM Employee
)
Tampaknya salah satu jawaban yang menerapkan klausa ORDER BY dalam solusi kehilangan intinya, atau tidak benar-benar memahami apa yang dikembalikan TOP kepada Anda.
TOP mengembalikan kumpulan hasil kueri tidak berurutan yang membatasi kumpulan rekaman ke catatan N pertama yang dikembalikan. (Dari perspektif Oracle, ini mirip dengan menambahkan tempat ROWNUM <(N + 1).
Solusi apa pun yang menggunakan urutan, dapat mengembalikan baris yang juga dikembalikan oleh klausa TOP (karena kumpulan data itu tidak diurutkan di tempat pertama), bergantung pada kriteria apa yang digunakan dalam urutan oleh
Kegunaan TOP adalah setelah dataset mencapai ukuran N tertentu, ia berhenti mengambil baris. Anda bisa merasakan seperti apa data itu tanpa harus mengambil semuanya.
Untuk mengimplementasikan BOTTOM secara akurat, itu perlu mengambil seluruh dataset tanpa urutan dan kemudian membatasi dataset ke N record akhir. Itu tidak akan efektif jika Anda berurusan dengan tabel besar. Juga tidak akan memberi Anda apa yang menurut Anda Anda minta. Akhir dari kumpulan data mungkin tidak selalu berupa "baris terakhir yang disisipkan" (dan mungkin tidak untuk sebagian besar aplikasi intensif DML).
Demikian pula, solusi yang menerapkan ORDER BY, sayangnya, berpotensi menjadi bencana saat menangani kumpulan data yang besar. Jika saya memiliki, katakanlah, 10 Miliar rekaman dan menginginkan 10 Miliar rekaman terakhir, sangatlah bodoh untuk memesan 10 Miliar rekaman dan memilih 10 yang terakhir.
Masalahnya di sini, BOTTOM tidak memiliki arti seperti yang kita pikirkan saat membandingkannya dengan TOP.
Saat catatan dimasukkan, dihapus, disisipkan, dihapus berulang kali, beberapa celah akan muncul di penyimpanan dan kemudian, baris akan ditempatkan, jika memungkinkan. Namun yang sering kita lihat, ketika kita memilih TOP, ternyata data sudah terurut, karena mungkin sudah disisipkan lebih awal pada keberadaan tabel. Jika tabel tidak mengalami banyak penghapusan, tabel tersebut mungkin tampak teratur. (mis. tanggal pembuatan mungkin sejauh pembuatan tabel itu sendiri). Tetapi kenyataannya adalah, jika ini adalah tabel dengan penghapusan berat, baris TOP N mungkin tidak terlihat seperti itu sama sekali.
Jadi - intinya di sini (permainan kata-kata) adalah bahwa seseorang yang meminta catatan BOTTOM N sebenarnya tidak tahu apa yang mereka minta. Atau, setidaknya, apa yang mereka minta dan apa arti BAWAH sebenarnya bukanlah hal yang sama.
Jadi - solusinya mungkin memenuhi kebutuhan bisnis sebenarnya dari pemohon ... tetapi tidak memenuhi kriteria untuk menjadi BAWAH.
insert
pernyataan besar untuk menempatkan baris ke dalam tabel besar yang tidak terindeks. (Saya mengisi tabel terlebih dahulu sebelum saya mulai mengindeksnya.) Saya kehilangan sesi klien saya karena reboot atau apa pun, dan sekarang saya ingin melihat apakah baris yang baru saya tambahkan ada di sana. Jika baris 'terbawah' di tabel adalah salah satu baris terbaru saya, saya tahu operasi telah selesai. Jika baris 'bawah' adalah sesuatu yang lain, yah tidak ada jaminan dan saya harus memindai seluruh tabel untuk memastikan ... tetapi kemungkinan besar saya dapat menghemat waktu dengan segera memeriksa 'bawah' seperti yang Anda bisa ' puncak'.
Jawaban yang diterima saat ini oleh "Justin Ethier" bukanlah jawaban yang benar seperti yang ditunjukkan oleh "Pelindung satu".
Sejauh yang saya bisa lihat, sampai sekarang, tidak ada jawaban atau komentar lain yang setara dengan BAWAH (x) pertanyaan yang diminta penulis.
Pertama, mari pertimbangkan skenario di mana fungsionalitas ini akan dibutuhkan:
SELECT * FROM Split('apple,orange,banana,apple,lime',',')
Ini mengembalikan tabel satu kolom dan lima catatan:
Seperti yang Anda lihat: kami tidak memiliki kolom ID; kami tidak dapat memesan berdasarkan kolom yang dikembalikan; dan kami tidak dapat memilih dua rekaman terbawah menggunakan SQL standar seperti yang dapat kami lakukan untuk dua rekaman teratas.
Inilah usaha saya untuk memberikan solusi:
SELECT * INTO #mytemptable FROM Split('apple,orange,banana,apple,lime',',')
ALTER TABLE #mytemptable ADD tempID INT IDENTITY
SELECT TOP 2 * FROM #mytemptable ORDER BY tempID DESC
DROP TABLE #mytemptable
Dan berikut ini solusi yang lebih lengkap:
SELECT * INTO #mytemptable FROM Split('apple,orange,banana,apple,lime',',')
ALTER TABLE #mytemptable ADD tempID INT IDENTITY
DELETE FROM #mytemptable WHERE tempID <= ((SELECT COUNT(*) FROM #mytemptable) - 2)
ALTER TABLE #mytemptable DROP COLUMN tempID
SELECT * FROM #mytemptable
DROP TABLE #mytemptable
Saya sama sekali tidak mengklaim bahwa ini adalah ide yang baik untuk digunakan dalam semua keadaan, tetapi ini memberikan hasil yang diinginkan.
Yang perlu Anda lakukan adalah membalik file ORDER BY
. Tambahkan atau hapus DESC
.
Masalah dengan memesan dengan cara lain adalah sering tidak memanfaatkan indeks dengan baik. Ini juga tidak terlalu dapat diperpanjang jika Anda perlu memilih sejumlah baris yang tidak di awal atau di akhir. Cara alternatifnya adalah sebagai berikut.
DECLARE @NumberOfRows int;
SET @NumberOfRows = (SELECT COUNT(*) FROM TheTable);
SELECT col1, col2,...
FROM (
SELECT col1, col2,..., ROW_NUMBER() OVER (ORDER BY col1) AS intRow
FROM TheTable
) AS T
WHERE intRow > @NumberOfRows - 20;
Jawaban "Tom H" di atas benar dan berhasil untuk saya dalam mendapatkan 5 baris Terbawah.
SELECT [KeyCol1], [KeyCol2], [Col3]
FROM
(SELECT TOP 5 [KeyCol1],
[KeyCol2],
[Col3]
FROM [dbo].[table_name]
ORDER BY [KeyCol1],[KeyCol2] DESC) SOME_ALAIS
ORDER BY [KeyCol1],[KeyCol2] ASC
Terima kasih.
coba ini.
declare @floor int --this is the offset from the bottom, the number of results to exclude
declare @resultLimit int --the number of results actually retrieved for use
declare @total int --just adds them up, the total number of results fetched initially
--following is for gathering top 60 results total, then getting rid of top 50. We only keep the last 10
set @floor = 50
set @resultLimit = 10
set @total = @floor + @resultLimit
declare @tmp0 table(
--table body
)
declare @tmp1 table(
--table body
)
--this line will drop the wanted results from whatever table we're selecting from
insert into @tmp0
select Top @total --what to select (the where, from, etc)
--using floor, insert the part we don't want into the second tmp table
insert into @tmp1
select top @floor * from @tmp0
--using select except, exclude top x results from the query
select * from @tmp0
except
select * from @tmp1
Saya telah menemukan solusi untuk ini yang tidak mengharuskan Anda mengetahui jumlah baris yang dikembalikan.
Misalnya, jika Anda ingin mendapatkan semua lokasi yang dicatat dalam tabel, kecuali yang terbaru 1 (atau 2, atau 5, atau 34)
SELECT *
FROM
(SELECT ROW_NUMBER() OVER (ORDER BY CreatedDate) AS Row, *
FROM Locations
WHERE UserId = 12345) AS SubQuery
WHERE Row > 1 -- or 2, or 5, or 34
SELECT TOP 10*from TABLE1 ORDER BY ID DESC
Dimana ID adalah kunci utama dari TABLE1.
Pertama, buat indeks di subkueri sesuai dengan urutan asli tabel menggunakan:
ROW_NUMBER () OVER (ORDER BY (SELECT NULL) ) AS RowIndex
Kemudian urutkan tabel dengan RowIndex
kolom yang Anda buat di kueri utama:
ORDER BY RowIndex DESC
Dan akhirnya gunakan TOP
dengan jumlah baris yang Anda inginkan:
SELECT TOP 1 * --(or 2, or 5, or 34)
FROM (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL) ) AS RowIndex, *
FROM MyTable) AS SubQuery
ORDER BY RowIndex DESC