ฉันมีคำถามนี้กับ MySQL:
select * from table1 LIMIT 10,20
ฉันจะทำสิ่งนี้กับ SQL Server ได้อย่างไร
ฉันมีคำถามนี้กับ MySQL:
select * from table1 LIMIT 10,20
ฉันจะทำสิ่งนี้กับ SQL Server ได้อย่างไร
คำตอบ:
เริ่มต้น SQL SERVER 2005 คุณสามารถทำได้ ...
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;
หรืออะไรทำนองนี้สำหรับรุ่นปี 2000 และต่ำกว่า ...
SELECT TOP 10 * FROM (SELECT TOP 20 FROM Table ORDER BY Id) ORDER BY Id DESC
Clunky แต่ก็ใช้ได้ผล
SELECT TOP 10 * FROM table WHERE id NOT IN (SELECT TOP 10 id FROM table ORDER BY id) FROM table ORDER BY id
การละเว้นข้อ LIMIT ของ MSSQL ถือเป็นความผิดทางอาญา IMO คุณไม่ควรต้องทำวิธีแก้ปัญหาแบบนี้
เริ่มต้นด้วย SQL SERVER 2012 คุณสามารถใช้คำสั่ง OFFSET FETCH:
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
สิ่งนี้อาจทำงานไม่ถูกต้องเมื่อลำดับโดยไม่ซ้ำกัน
ถ้าแบบสอบถามถูกแก้ไขเป็น ORDER BY OrderDate ชุดผลลัพธ์ที่ส่งคืนจะไม่เป็นไปตามที่คาดไว้
นี่เกือบจะซ้ำกับคำถามที่ฉันถามในเดือนตุลาคม: เลียนแบบคำสั่ง MySQL LIMIT ใน Microsoft SQL Server 2000
หากคุณใช้ Microsoft SQL Server 2000 ไม่มีวิธีแก้ปัญหาที่ดี คนส่วนใหญ่ต้องใช้การบันทึกผลลัพธ์ของแบบสอบถามในตารางชั่วคราวด้วยIDENTITY
คีย์หลัก จากนั้นสอบถามกับคอลัมน์คีย์หลักโดยใช้BETWEEN
เงื่อนไข
หากคุณใช้ Microsoft SQL Server 2005 หรือใหม่กว่าคุณมีROW_NUMBER()
ฟังก์ชันดังนั้นคุณจะได้รับผลลัพธ์เดียวกัน แต่หลีกเลี่ยงตารางชั่วคราว
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 @offset+@count;
นอกจากนี้คุณยังสามารถเขียนนี้เป็นแสดงออกตารางที่พบบ่อยตามที่แสดงใน @ ลีออง Tayson ของคำตอบ
นี่คือวิธีที่ฉัน จำกัด ผลลัพธ์ใน MS SQL Server 2012:
SELECT *
FROM table1
ORDER BY columnName
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY
หมายเหตุ: OFFSET
สามารถใช้ร่วมกับORDER BY
.
เพื่ออธิบายสายรหัส OFFSET xx ROWS FETCH NEXT yy ROW ONLY
xx
เป็นจำนวนบันทึก / แถวที่คุณต้องการที่จะเริ่มต้นจากการดึงในตารางคือ: ถ้ามี 40 ระเบียนในตารางที่ 1 รหัสดังกล่าวข้างต้นจะเริ่มดึงจากแถว 10
yy
เป็นจำนวนของระเบียน / แถวที่คุณต้องการที่จะดึงจากตาราง
เพื่อสร้างจากตัวอย่างก่อนหน้านี้: หากตารางที่ 1 มี 40 ระเบียนและคุณเริ่มดึงจากแถว 10 และคว้าชุดถัดไปเป็น 10 (yy
) นั่นหมายความว่าโค้ดด้านบนจะดึงระเบียนจากตาราง 1 โดยเริ่มจากแถวที่ 10 และสิ้นสุดที่ 20 ดังนั้นจึงดึงแถวที่ 10 - 20
ตรวจสอบลิงค์สำหรับข้อมูลเพิ่มเติมเกี่ยวกับOFFSET
SELECT *
FROM (
SELECT TOP 20
t.*, ROW_NUMBER() OVER (ORDER BY field1) AS rn
FROM table1 t
ORDER BY
field1
) t
WHERE rn > 10
แบบสอบถาม MySQL LIMIT เชิงไวยากรณ์เป็นดังนี้:
SELECT * FROM table LIMIT OFFSET, ROW_COUNT
สิ่งนี้สามารถแปลเป็น Microsoft SQL Server เช่น
SELECT * FROM
(
SELECT TOP #{OFFSET+ROW_COUNT} *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum
FROM table
) a
WHERE rnum > OFFSET
ตอนนี้คำถามของคุณselect * from table1 LIMIT 10,20
จะเป็นดังนี้:
SELECT * FROM
(
SELECT TOP 30 *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum
FROM table1
) a
WHERE rnum > 10
นี่เป็นหนึ่งในเหตุผลที่ฉันพยายามหลีกเลี่ยงการใช้ MS Server ... แต่อย่างไรก็ตาม บางครั้งคุณก็ไม่มีตัวเลือก (เย้! และฉันต้องใช้เวอร์ชันที่ล้าสมัย !!)
คำแนะนำของฉันคือการสร้างตารางเสมือน:
จาก:
SELECT * FROM table
ถึง:
CREATE VIEW v_table AS
SELECT ROW_NUMBER() OVER (ORDER BY table_key) AS row,* FROM table
จากนั้นเพียงแค่สอบถาม:
SELECT * FROM v_table WHERE row BETWEEN 10 AND 20
หากมีการเพิ่มหรือลบช่อง "แถว" จะอัปเดตโดยอัตโนมัติ
ปัญหาหลักของตัวเลือกนี้คือ ORDER BY ได้รับการแก้ไข ดังนั้นหากคุณต้องการคำสั่งอื่นคุณจะต้องสร้างมุมมองอื่น
UPDATE
มีปัญหาอีกอย่างในแนวทางนี้: หากคุณพยายามกรองข้อมูลของคุณจะไม่ได้ผลตามที่คาดไว้ ตัวอย่างเช่นหากคุณทำ:
SELECT * FROM v_table WHERE field = 'test' AND row BETWEEN 10 AND 20
WHERE จะ จำกัด เฉพาะข้อมูลที่อยู่ในแถวระหว่าง 10 ถึง 20 (แทนที่จะค้นหาชุดข้อมูลทั้งหมดและ จำกัด เอาต์พุต)
นี่เป็นแนวทางหลายขั้นตอนที่จะทำงานใน 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
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;
ต้องลอง. ในแบบสอบถามด้านล่างคุณสามารถดูจัดกลุ่มตามลำดับโดยข้ามแถวและ จำกัด แถว
select emp_no , sum(salary_amount) from emp_salary
Group by emp_no
ORDER BY emp_no
OFFSET 5 ROWS -- Skip first 5
FETCH NEXT 10 ROWS ONLY; -- limit to retrieve next 10 row after skiping rows
SELECT TOP 10 * FROM table;
ก็เหมือนกับ
SELECT * FROM table LIMIT 0,10;
นี่คือบทความเกี่ยวกับการใช้ Limit ใน MsSQLเป็นการอ่านที่ดีโดยเฉพาะความคิดเห็น
ใน SQL ไม่มีคำหลัก LIMIT อยู่ หากคุณต้องการจำนวนแถวที่ จำกัด คุณควรใช้คำหลัก TOP ซึ่งคล้ายกับ LIMIT
หาก ID ของคุณเป็นประเภทตัวระบุที่ไม่ซ้ำกันหรือ ID ของคุณในตารางไม่ได้รับการจัดเรียงคุณต้องทำเช่นนี้ด้านล่าง
select * from
(select ROW_NUMBER() OVER (ORDER BY (select 0)) AS RowNumber,* from table1) a
where a.RowNumber between 2 and 5
รหัสจะเป็น
เลือก * จากขีด จำกัด 2,5
ใช้สิ่งนี้ได้ดีกว่าใน MSSQLExpress 2017
SELECT * FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) as [Count], * FROM table1
) as a
WHERE [Count] BETWEEN 10 and 20;
- ให้คอลัมน์ [Count] และกำหนดให้ทุกแถวมีการนับที่ไม่ซ้ำกันโดยไม่ต้องสั่งซื้อบางอย่างจากนั้นเลือกอีกครั้งที่คุณสามารถระบุขีด จำกัด ของคุณได้ .. :)
วิธีหนึ่งที่เป็นไปได้ที่จะได้รับผลลัพธ์ดังต่อไปนี้หวังว่านี่จะช่วยได้
declare @start int
declare @end int
SET @start = '5000'; -- 0 , 5000 ,
SET @end = '10000'; -- 5001, 10001
SELECT * FROM (
SELECT TABLE_NAME,TABLE_TYPE, ROW_NUMBER() OVER (ORDER BY TABLE_NAME) as row FROM information_schema.tables
) a WHERE a.row > @start and a.row <= @end
ทางที่ง่าย
ข้อมูล MySQL:
SELECT 'filds' FROM 'table' WHERE 'where' LIMIT 'offset','per_page'
MSSQL:
SELECT 'filds' FROM 'table' WHERE 'where' ORDER BY 'any' OFFSET 'offset'
ROWS FETCH NEXT 'per_page' ROWS ONLY
ORDER BY เป็นข้อบังคับ
ถ้าฉันจำไม่ผิด (เป็นเวลานานแล้วที่ฉันใช้ SQL Server) คุณอาจสามารถใช้สิ่งนี้ได้: (2005 ขึ้นไป)
SELECT
*
,ROW_NUMBER() OVER(ORDER BY SomeFields) AS [RowNum]
FROM SomeTable
WHERE RowNum BETWEEN 10 AND 20
WHERE
นามแฝงที่กำหนดไว้ในSELECT
ประโยคระดับเดียวกัน