2009-03-02 28 views
85

Tôi có truy vấn này với mysql:Cách triển khai LIMIT với Microsoft SQL Server?

select * from table1 LIMIT 10,20 

Làm thế nào tôi có thể làm điều này với Microsoft sql?

+0

bản sao có thể có của [LIMIT 10..20 trong SQL Server] (http://stackoverflow.com/questions/971964/limit-10-20-in-sql-server) – assylias

+10

Vì câu hỏi này được hỏi trước, nên Câu hỏi khác là bản sao? –

+0

Xem: [Tôi có nên gắn cờ câu hỏi là trùng lặp nếu câu hỏi đã nhận được câu trả lời hay hơn không?] (Https://meta.stackoverflow.com/q/251938/55075) – kenorb

Trả lời

94

Bắt đầu từ SQL SERVER 2005, bạn có thể làm điều này ...

USE AdventureWorks; 
GO 
WITH OrderedOrders AS 
(
    SELECT SalesOrderID, OrderDate, 
    ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber' 
    FROM Sales.SalesOrderHeader 
) 
SELECT * 
FROM OrderedOrders 
WHERE RowNumber BETWEEN 10 AND 20; 

hoặc một cái gì đó như thế này cho năm 2000 và dưới các phiên bản ...

SELECT TOP 10 * FROM (SELECT TOP 20 FROM Table ORDER BY Id) ORDER BY Id DESC 
+5

Truy vấn thứ 2 không thành công nếu bạn có, ví dụ: 14 hàng trong bảng. Nó cung cấp cho bạn các hàng từ 5 đến 14, nhưng bạn muốn các hàng từ 11 đến 14. Nói chung, nó không thành công cho "trang" cuối cùng của một kết quả, trừ khi tổng số hàng là bội số của kích thước "trang" đó. –

+0

Bạn nói đúng ... chưa thử nghiệm nó :) –

+84

Điều đơn giản như vậy cần phải được thực hiện rất khó khăn bởi MS một lần nữa! – Martin

-6
SELECT TOP 10 * FROM table; 

là giống như

SELECT * FROM table LIMIT 0,10; 

Here's an article about implementing Limit in MsSQL Its a thoải mái đọc, đặc biệt ý kiến.

+1

Cảm ơn, nhưng tôi muốn có hồ sơ từ 10 đến 20, một cách để làm điều đó? – Bigballs

+1

này _only ever_ nhận được các hàng từ đầu tập kết quả ... –

+2

Câu trả lời này không trả lời câu hỏi gốc, nhưng nó hữu ích nếu một người như tôi cần biết cách lấy kết quả N đầu tiên và đến đây qua google etc ... – brianlmerritt

41

Clunky, nhưng nó sẽ hoạt động.

SELECT TOP 10 * FROM table WHERE id NOT IN (SELECT TOP 10 id FROM table ORDER BY id) FROM table ORDER BY id 

Bỏ qua MSSQL của mệnh đề LIMIT là hình sự, IMO. Bạn không cần phải làm kiểu giải pháp kludy này.

+0

Bạn có đề xuất nào khác để bỏ qua điều này không? – Bigballs

+0

Tôi đã làm rất nhiều Googling lần cuối cùng tôi đã phải đối phó với MSSQL và đây là giải pháp tốt nhất tôi tìm thấy. Không dễ chịu, nhưng nó hoạt động. – ceejayoz

+0

Giải pháp này chỉ hoạt động nếu tập hợp kết quả bao gồm một cột duy nhất. Nó không phải là một giải pháp chung để bắt chước LIMIT cho bất kỳ truy vấn nào. –

-2

Nếu tôi nhớ chính xác (nó được một trong khi kể từ khi tôi dabbed với SQL Server) bạn có thể sử dụng một cái gì đó như thế này: (2005 và lên)

SELECT 
    * 
    ,ROW_NUMBER() OVER(ORDER BY SomeFields) AS [RowNum] 
FROM SomeTable 
WHERE RowNum BETWEEN 10 AND 20 
+0

SQL Server 2012: Msg 207, Cấp 16, Tiểu bang 1, Dòng 5 Tên cột không hợp lệ 'RowNum'. –

+0

có vẻ như bạn có lỗi đánh máy trong tuyên bố của mình ở đâu đó. RowNum là tên mà chúng ta gán cho biểu thức. Đăng vấn đề của bạn với nguồn và cộng đồng sẽ giúp bạn – Kris

+0

Đây không phải là cú pháp hợp lệ. Bạn không thể tham chiếu trong 'WHERE' một bí danh được định nghĩa trong cùng một mệnh đề' SELECT'. –

18

Đây là al hầu hết bản sao của câu hỏi tôi đã hỏi vào tháng 10: Emulate MySQL LIMIT clause in Microsoft SQL Server 2000

Nếu bạn đang sử dụng Microsoft SQL Server 2000, không có giải pháp tốt. Hầu hết mọi người phải nghỉ mát để chụp kết quả truy vấn trong bảng tạm thời với khóa chính IDENTITY. Sau đó truy vấn đối với cột khóa chính sử dụng điều kiện BETWEEN.

Nếu bạn đang sử dụng Microsoft SQL Server 2005 trở lên, bạn có chức năng ROW_NUMBER(), vì vậy bạn có thể nhận được kết quả tương tự nhưng tránh bảng tạm thời.

SELECT t1.* 
FROM (
    SELECT ROW_NUMBER OVER(ORDER BY id) AS row, t1.* 
    FROM (...original SQL query...) t1 
) t2 
WHERE t2.row BETWEEN @offset+1 AND @[email protected]; 

Bạn cũng có thể viết những dòng này như một common table expression như trong @Leon Tây Sơn của answer.

+0

ROW_NUMBER() OVER (ORDER BY) được điểm cho hợp lệ trong ANSI SQL: 2003, mặc dù hỗ trợ trong DBMS ngoài SQL Server là rất spotty. Và nó khá là khó khăn tất nhiên ... – bobince

+0

@bobince: Nó chỉ ra Oracle, Microsoft SQL Server 2005, IBM DB2 và PostgreSQL 8.4 tất cả các chức năng cửa sổ hỗ trợ. Điều đó bao gồm phần lớn thị trường SQL. Hỗ trợ chỉ là spotty nếu bạn sử dụng MySQL, SQLite hoặc một phiên bản cũ của DB ở trên. –

11
SELECT * 
FROM (
     SELECT TOP 20 
       t.*, ROW_NUMBER() OVER (ORDER BY field1) AS rn 
     FROM table1 t 
     ORDER BY 
       field1 
     ) t 
WHERE rn > 10 
+0

Vâng, tôi vừa kiểm tra, SQL Server hóa ra đủ thông minh để dừng lại trên ROW_NUMBER() điều kiện, nếu có một cột được lập chỉ mục trong mệnh đề ORDER BY. – Quassnoi

1

Đây là phương pháp tiếp cận nhiều bước sẽ hoạt động trong SQL2000.

-- Create a temp table to hold the data 
CREATE TABLE #foo(rowID int identity(1, 1), myOtherColumns) 

INSERT INTO #foo (myColumns) SELECT myData order By MyCriteria 

Select * FROM #foo where rowID > 10 
8

Cú pháp MySQL LIMIT truy vấn là một cái gì đó như thế này:

SELECT * FROM table LIMIT OFFSET, ROW_COUNT 

này có thể được dịch sang Microsoft SQL Server như

SELECT * FROM 
(
    SELECT TOP #{OFFSET+ROW_COUNT} *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum 
    FROM table 
) a 
WHERE rnum > OFFSET 

Bây giờ truy vấn của bạn select * from table1 LIMIT 10,20 sẽ như thế này:

SELECT * FROM 
(
    SELECT TOP 30 *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum 
    FROM table1 
) a 
WHERE rnum > 10 
1
SELECT 
    * 
FROM 
    (
     SELECT 
      top 20    -- ($a) number of records to show 
      * 
     FROM 
      (
       SELECT 
        top 29  -- ($b) last record position 
        * 
       FROM 
        table  -- replace this for table name (i.e. "Customer") 
       ORDER BY 
        2 ASC 
      ) AS tbl1 
     ORDER BY 
      2 DESC 
    ) AS tbl2 
ORDER BY 
    2 ASC; 

-- Examples: 

-- Show 5 records from position 5: 
-- $a = 5; 
-- $b = (5 + 5) - 1 
-- $b = 9; 

-- Show 10 records from position 4: 
-- $a = 10; 
-- $b = (10 + 4) - 1 
-- $b = 13; 

-- To calculate $b: 
-- $b = ($a + position) - 1 

-- For the present exercise we need to: 
-- Show 20 records from position 10: 
-- $a = 20; 
-- $b = (20 + 10) - 1 
-- $b = 29; 
+0

Là một giải pháp tuyệt vời cho tôi. – Tyde

2

Đây là một trong những lý do tôi cố gắng tránh sử dụng MS Server ... nhưng dù sao đi nữa.Đôi khi bạn không có tùy chọn (yei! Và tôi phải sử dụng một phiên bản lỗi thời !!).

Đề nghị của tôi là tạo ra một bảng ảo:

Từ:

SELECT * FROM table 

Để:

CREATE VIEW v_table AS  
    SELECT ROW_NUMBER() OVER (ORDER BY table_key) AS row,* FROM table 

Sau đó chỉ cần truy vấn:

SELECT * FROM v_table WHERE row BETWEEN 10 AND 20 

Nếu lĩnh vực được bổ sung hoặc bị xóa, "hàng" là được cập nhật tự động.

Vấn đề chính với tùy chọn này là ORDER BY đã được sửa. Vì vậy, nếu bạn muốn một thứ tự khác, bạn sẽ phải tạo một chế độ xem khác.

CẬP NHẬT

Có một vấn đề với cách tiếp cận này: nếu bạn cố gắng để lọc dữ liệu của bạn, nó sẽ không hoạt động như mong đợi. Ví dụ: nếu bạn thực hiện:

SELECT * FROM v_table WHERE field = 'test' AND row BETWEEN 10 AND 20 

Ở đó bị giới hạn ở những dữ liệu nằm trong hàng từ 10 đến 20 (thay vì tìm kiếm toàn bộ tập dữ liệu và giới hạn đầu ra).

16

Bắt đầu với SQL SERVER 2012, bạn có thể sử dụng OFFSET FETCH khoản:

USE AdventureWorks; 
GO 
SELECT SalesOrderID, OrderDate 
FROM Sales.SalesOrderHeader 
ORDER BY SalesOrderID 
    OFFSET 10 ROWS 
    FETCH NEXT 10 ROWS ONLY; 
GO 

http://msdn.microsoft.com/en-us/library/ms188385(v=sql.110).aspx

này có thể không hoạt động chính xác khi trình tự do không phải là độc đáo.

Nếu truy vấn được sửa đổi thành ORDER BY OrderDate, tập kết quả trả về không như mong đợi.

+0

Sử dụng 'with' chỉ cần một nửa thời gian để kết thúc truy vấn - xem câu trả lời của @Leon Tayson. Tôi không biết Microsoft đã làm gì để làm chậm. – isHuman

+0

Tại sao đây không phải là câu trả lời được chấp nhận? Chúng tôi đang ở trong ** 2018 ** vì đã khóc to! – Skipper

8

Đây là cách tôi giới hạn kết quả trong MS SQL Server 2012

SELECT * 
FROM table1 
ORDER BY columnName 
    OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY 

LƯU Ý: OFFSET chỉ có thể được sử dụng có hoặc song song ORDER BY.

Để giải thích các dòng mã OFFSET ROWS xx Lấy NEXT yy ROW CHỈ

Các "xx" là con số kỷ lục/hàng bạn muốn bắt đầu kéo từ trong bảng.
IE: Nếu có 40 bản ghi trong bảng 1. Mã ở trên sẽ bắt đầu kéo từ hàng 10.

"yy" là số lượng bản ghi/hàng bạn muốn kéo ra khỏi bảng.
Để xây dựng trên ví dụ trước.
IE: Nếu bảng 1 có 40 bản ghi và bạn bắt đầu kéo từ hàng 10 và lấy bộ TIẾP THEO 10 (yy).
Điều đó có nghĩa, các mã trên sẽ kéo bản ghi từ bảng 1 bắt đầu từ hàng 10 và kết thúc tại 20. Như vậy hàng kéo 10 - 20.

Kiểm tra các liên kết để biết thêm về OFFSET

0

Trong SQL không tồn tại từ khóa LIMIT nào.Nếu bạn chỉ cần một số hàng hạn chế, bạn nên sử dụng từ khóa TOP tương tự như LIMIT.

Các vấn đề liên quan