SQL Server로 LIMIT를 구현하는 방법은 무엇입니까?


답변:


127

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

6
예를 들어 테이블에 14 개의 행이 있으면 두 번째 쿼리가 실패합니다. 행 5-14를 제공하지만 행 11-14를 원합니다. 일반적으로 총 행이 해당 "페이지"크기의 배수가 아니면 결과의 마지막 "페이지"에 대해 실패합니다.
Bill Karwin

147
이러한 간단한 일은 MS에 의해 또 다시 어려워 질 필요가 있습니다!
Martin

SQL Server Management Studio 2017에서 나를 위해 일한 것은 다음과 같습니다. SELECT * FROM [dbo]. <insert tableName here> WHERE @@ ROWCOUNT BETWEEN <insert min here> 및 <insert max here>
Artorias2718

그냥 환상적인, MS SQL 서버 2017 SELECT 문에서 매력처럼 작품
PatsonLeaner

58

어리석은 일이지만 효과가 있습니다.

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

MSSQL의 LIMIT 절 누락은 형사 IMO입니다. 이런 종류의 복잡한 해결 방법을 수행하지 않아도됩니다.


이것을 우회하라는 또 다른 제안이 있습니까?
Bigballs

마지막으로 MSSQL을 다루어야 할 때 많은 인터넷 검색을 수행했으며 이것이 내가 찾은 최고의 솔루션이었습니다. 유쾌하지는 않지만 작동합니다.
ceejayoz 2016 년

이 솔루션은 결과 집합에 고유 한 열이 포함 된 경우에만 작동합니다. 모든 쿼리에 대해 LIMIT를 모방하는 일반적인 솔루션은 아닙니다.
Bill Karwin

1
나는 지금 비슷한 수준에 있습니다 ... 그러나 내 경우에는 호스가 있습니다 ... 소위 '전문가'dba가 테이블에서 불필요한 고유 키를 결정하면 더 범죄 적입니다 ... ... 외래 키와 제약 조건을 제기하지 마십시오!
Andrew Rollings

이것의 문제는 WHERE 절을 잘 처리하지 못한다는 것입니다 ... 나는 임시 테이블을 시도 할 것입니다.
불쾌한 페이스트리

37

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

by by가 고유하지 않으면 올바르게 작동하지 않을 수 있습니다.

조회가 ORDER BY OrderDate로 수정되면 리턴 된 결과 세트가 예상과 다릅니다.


'with'를 사용하면 쿼리를 완료하는 데 절반의 시간 만 필요합니다. @Leon Tayson의 답변을 참조하십시오. 나는 Microsoft가 그것을 느리게하기 위해 무엇을했는지 전혀 모른다.
isHuman

1
이것이 왜 받아 들여지지 않습니까? 우리는 2018 년 에 크게 울부 짖었습니다!
Skipper

1
@ 스키퍼 맞아. 받아 들여진 것은 여전히 ​​작동합니다. 업데이트를 반영하기 위해 이것을 상향 조정합시다.
kronn

18

이것은 10 월에 제가 물었던 질문과 거의 같습니다 : Microsoft SQL Server 2000의 MySQL LIMIT 절 에뮬레이션

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;

@Leon Tayson의 답변에 표시된 것처럼 이것을 공통 테이블 표현식 으로 작성할 수도 있습니다 .


ROW_NUMBER () OVER (ORDER BY)는 ANSI SQL : 2003에서 유효한 점수를 얻지 만 SQL Server 이외의 DBMS 지원은 매우 드물다. 그리고 그것은 물론 꽤 어색합니다 ...
bobince

@bobince : Oracle, Microsoft SQL Server 2005, IBM DB2 및 PostgreSQL 8.4는 모두 창 기능을 지원합니다. 이는 SQL 시장의 대부분을 차지합니다. MySQL, SQLite 또는 이전 버전의 DB를 사용하는 경우에만 지원이 명확합니다.
Bill Karwin

16

이것이 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당신이 테이블, 즉에서에서 당겨 시작하려는 레코드 / 행 번호입니다 : 표 1 (40 개) 기록이있는 경우, 위의 코드는 행 (10)으로부터 당겨 시작됩니다.

yy당신이 테이블에서 끌어 할 기록 / 행의 수입니다.

이전 예제를 빌드하려면 다음을 수행하십시오. 테이블 1에 40 개의 레코드가 있고 10 행에서 가져 오기 시작하고 NEXT 세트 10 ( yy)을 가져 오십시오 . 즉, 위의 코드는 행 10에서 시작하여 20에서 끝나는 테이블 1에서 레코드를 가져옵니다. 따라서 행 10-20을 가져옵니다.

OFFSET 에 대한 자세한 정보는 링크를 확인하십시오.


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

방금 확인한 것은 ORDER BY 절에 인덱싱 된 열이 있으면 SQL Server가 ROW_NUMBER () 조건에서 중지 할만 큼 똑똑한 것으로 판명되었습니다.
Quassnoi

9

문법적으로 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 

2

이것이 내가 MS 서버를 사용하지 않는 이유 중 하나입니다 ...하지만 어쨌든. 때로는 옵션이 없습니다 (yei! 및 오래된 버전을 사용해야합니다!).

내 제안은 가상 테이블을 만드는 것입니다.

에서:

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가 수정되었다는 것입니다. 따라서 다른 순서를 원하면 다른보기를 작성해야합니다.

최신 정보

이 방법에는 또 다른 문제가 있습니다. 데이터를 필터링하려고하면 예상대로 작동하지 않습니다. 예를 들어, 다음과 같은 경우 :

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

WHERE는 전체 데이터 세트를 검색하고 출력을 제한하는 대신 10에서 20 사이의 행에있는 데이터로 제한됩니다.


1

이것은 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

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;

나를 위해 훌륭한 솔루션이었습니다.
Tyde

1

꼭 해봐. 아래 쿼리에서 그룹 기준, 순서 기준, 행 건너 뛰기 및 행 제한을 볼 수 있습니다.

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

0
SELECT TOP 10 * FROM table;

와 같다

SELECT * FROM table LIMIT 0,10;

다음은 MsSQL에서 Limit를 구현하는 방법에 대한 기사 입니다.


1
고맙지 만 10과 20 사이의 기록을 원합니다. 할 수있는 방법이 있습니까?
Bigballs

5
이 답변은 원래 질문에 응답하지 않지만 나와 같은 누군가가 첫 번째 N 결과를 얻는 방법을 알아야하고 Google 등을 통해 여기에 온 경우 유용합니다.
brianlmerritt

0

SQL에는 LIMIT 키워드가 없습니다. 제한된 수의 행만 필요한 경우 LIMIT와 유사한 TOP 키워드를 사용해야합니다.


0

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까지 선택

0

MSSQLExpress 2017에서 더 잘 사용하십시오.

SELECT * FROM
(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) as [Count], * FROM table1
) as a
WHERE [Count] BETWEEN 10 and 20;

-열 [카운트]를 제공하고 무언가를 주문하지 않고 모든 행에 고유 한 카운팅을 할당 한 다음 한계를 제공 할 수있는 위치에서 다시 선택하십시오 .. :)


0

아래와 같이 결과를 얻는 가능한 방법 중 하나가 도움이되기를 바랍니다.

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

0

쉬운 방법

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

주문은 필수입니다


-2

내가 올바르게 기억한다면 (SQL Server를 다루기 시작한지 ​​오래되었습니다) 다음과 같은 것을 사용할 수 있습니다 : (2005 이상)

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

SQL Server 2012 : 메시지 207, 수준 16, 상태 1, 줄 5 잘못된 열 이름 'RowNum'입니다.
e-info128 2016 년

당신은 어딘가에 당신의 진술에 오타가있는 것처럼 들립니다. RowNum은 식에 할당 한 이름입니다. 출처에 문제를 게시하면 커뮤니티가 도움을 줄 것입니다.
Kris

유효한 구문이 아닙니다. WHERE동일한 레벨 SELECT절에 정의 된 별칭을 참조 할 수 없습니다 .
ypercubeᵀᴹ
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.