2010-05-28 36 views
12

Tôi đang sử dụng SQL Server 2005 và tôi đang cố gắng đạt được một cái gì đó như thế này: Tôi muốn nhận được các hàng x đầu tiên và x hàng cuối cùng trong cùng một câu lệnh chọn.Chọn hàng trên cùng và dưới cùng

SELECT TOP(5) BOTTOM(5) 

Tất nhiên BOTTOM không tồn tại, vì vậy tôi cần một giải pháp khác. Tôi tin rằng có một giải pháp dễ dàng và thanh lịch mà tôi không nhận được. Việc chọn lại lần nữa với GROUP BY DESC không phải là một tùy chọn.

Trả lời

22

Sử dụng một công đoàn là điều duy nhất tôi có thể nghĩ ra để thực hiện điều này

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

Ngoài ra còn có cách sử dụng rownumber . Và bạn nên đứng đầu 2. – hgulyan

+1

@hgulyan: TOP (x) là phương thức ưa thích - nó cũng hoạt động với UPDATE và DELETE, và cũng cho phép bạn viết 'TOP (20%)' hoặc 'TOP (@limit)' và như vậy là –

+0

Không biết điều đó. Cảm ơn vì thông tin. – hgulyan

8

Kiểm tra liên kết

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

Bạn đã cố gắng sử dụng rownumber?

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

mã này sẽ không hoạt động. 'Top5' và' Bottom5' không thể được tham chiếu như thế này, bạn nhận được 'Msg 207, Level 16, State 1, Line 4 Tên cột không hợp lệ 'TopFive' ...' Nếu bạn đặt 'ROW_NUMBER ...'trong WHERE bạn nhận được các hàm Msg 4108, Level 15, State 1, Line 1 chỉ có thể xuất hiện trong mệnh đề SELECT hoặc ORDER BY.' Bạn cần bọc SELECT và FROM trong bảng có nguồn gốc và kéo WHERE đến truy vấn bên ngoài để làm việc này, như [@Paul đã làm trong phương thức thứ hai trong câu trả lời của anh ấy] (http://stackoverflow.com/questions/2927475/sql-server-select-top-and-bottom-rows/2927515#2927515). –

+0

Truy vấn đã chỉnh sửa. Đó là một sai lầm lớn. – hgulyan

+1

Điều này sẽ chạy như một con chó không có chân. Sử dụng UNION – gbn

1

Sau đó, bạn đang ra - làm chọn một lần nữa LÀ lựa chọn duy nhất, trừ khi bạn muốn kéo trong kết quả hoàn tất thiết lập và sau đó ném đi tất cả mọi thứ ở giữa. Bất kỳ sql tôi nghĩ là cùng một cách - cho phía dưới, bạn cần phải biết đầu tiên hoặc có bao nhiêu mục bạn có (materialize tất cả mọi thứ hoặc sử dụng đếm (*)) hoặc một thứ tự sắp xếp ngược lại.

Xin lỗi nếu điều đó không phù hợp với bạn, nhưng cuối cùng .... thực tế không quan tâm, và tôi không thấy bất kỳ cách nào khác để làm điều đó.

1

tôi đoán bạn phải làm điều đó bằng subquery chỉ

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) 
) 

EDITED

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

Đó là máy chủ sql, vì vậy thay vì LIMIT, bạn cần sử dụng TOP – hgulyan

+0

oohhhhhhhhh thanx @hgulyan i chỉnh sửa nó có thể giúp :) – Salil

+0

Msg 156, Level 15, State 1, Line 3 Cú pháp không chính xác gần từ khóa 'ORDER'. –

3

Nó có phải là một lựa chọn để bạn sử dụng một công đoàn?

Ví dụ:

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

Nếu bạn đăng mã, * vui lòng * làm nổi bật các dòng và nhấp vào nút "mã" (101 010) trên thanh công cụ của trình soạn thảo! –

7

Tôi nghĩ rằng bạn đã hai lựa chọn chính:

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

UNION 

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

Hoặc, nếu bạn biết có bao nhiêu mặt hàng có trong bảng:

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

Không khác biệt thực sự giữa điều này và công đoàn mà tôi biết, nhưng về mặt kỹ thuật, đó là một truy vấn đơn lẻ.

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

Gần đây tôi phải thực hiện quy trình lưu trữ rất lớn; nếu truy vấn của bạn khá lớn và bạn muốn giảm thiểu số truy vấn bạn có thể khai báo @tempTable, hãy chèn vào @tempTable đó rồi truy vấn từ @tempTable,

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 
Các vấn đề liên quan