Khi tôi làm việc trên Zend Framework's database component, chúng tôi đã cố gắng trừu tượng hóa chức năng của mệnh đề LIMIT
được hỗ trợ bởi MySQL, PostgreSQL và SQLite. Đó là, tạo ra một truy vấn có thể được thực hiện theo cách này:Giả lập mệnh đề LIMIT của MySQL trong Microsoft SQL Server 2000
$select = $db->select();
$select->from('mytable');
$select->order('somecolumn');
$select->limit(10, 20);
Khi cơ sở dữ liệu hỗ trợ LIMIT
, điều này tạo ra một truy vấn SQL như sau:
SELECT * FROM mytable ORDER BY somecolumn LIMIT 10, 20
này được phức tạp hơn cho các thương hiệu của cơ sở dữ liệu không hỗ trợ LIMIT
(mệnh đề đó không phải là một phần của ngôn ngữ SQL chuẩn, nhân tiện). Nếu bạn có thể tạo số hàng, hãy đặt toàn bộ truy vấn một bảng dẫn xuất và truy vấn bên ngoài sử dụng BETWEEN
. Đây là giải pháp cho Oracle và IBM DB2. Microsoft SQL Server 2005 có một chức năng hàng-số tương tự, vì vậy người ta có thể viết các truy vấn theo cách này:
SELECT z2.*
FROM (
SELECT ROW_NUMBER OVER(ORDER BY id) AS zend_db_rownum, z1.*
FROM (...original SQL query...) z1
) z2
WHERE z2.zend_db_rownum BETWEEN @offset+1 AND @[email protected];
Tuy nhiên, Microsoft SQL Server 2000 không có ROW_NUMBER()
chức năng.
Vì vậy, câu hỏi của tôi là, bạn có thể đưa ra một cách để mô phỏng chức năng LIMIT
trong Microsoft SQL Server 2000, chỉ sử dụng SQL? Không sử dụng con trỏ hoặc T-SQL hoặc thủ tục lưu sẵn. Nó phải hỗ trợ cả hai đối số cho LIMIT
, cả đếm và bù. Các giải pháp sử dụng bảng tạm thời cũng không được chấp nhận.
Edit:
Các giải pháp phổ biến nhất cho MS SQL Server 2000 có vẻ là như hình dưới đây, ví dụ để có được hàng 50 đến 75:
SELECT TOP 25 *
FROM (
SELECT TOP 75 *
FROM table
ORDER BY BY field ASC
) a
ORDER BY field DESC;
Tuy nhiên, điều này doesn' t làm việc nếu tổng số kết quả là, nói 60 hàng. Truy vấn bên trong trả về 60 hàng vì nó nằm trong 75 đầu. Sau đó truy vấn bên ngoài trả về các hàng 35-60, không phù hợp với "trang" mong muốn của 50-75. Về cơ bản, giải pháp này hoạt động trừ khi bạn cần "trang" cuối cùng của tập hợp kết quả không xảy ra là bội số của kích thước trang.
Edit:
Một giải pháp khác hoạt động tốt hơn, nhưng chỉ khi bạn có thể giả định tập hợp kết quả bao gồm một cột mà là duy nhất:
SELECT TOP n *
FROM tablename
WHERE key NOT IN (
SELECT TOP x key
FROM tablename
ORDER BY key
);
Kết luận:
Không chung giải pháp đa năng dường như tồn tại để mô phỏng LIMIT
trong MS SQL Server 2000. Một giải pháp tốt tồn tại nếu bạn có thể sử dụng ROW_NUMBER()
funct ion trong MS SQL Server 2005.
Có, đây là gần, nhưng nó chỉ hoạt động khi có một chìa khóa duy nhất trong kết quả truy vấn tạm thời. Làm thế nào bạn sẽ làm điều đó trong một truy vấn GROUP BY hoặc cho một truy vấn tham gia nhiều bảng? –