문제

나에 관심있는 학습을 일(문)데이터베이스의 독립적 방법의 선택 n번째 행에서 데이터베이스 테이블.는 것도 흥미로운 볼 이를 수행할 수 있는 방법을 사용하는 기본 기능은 다음과 같은 데이터베이스:

  • SQL Server
  • MySQL
  • PostgreSQL
  • SQLite
  • Oracle

나는 현재와 같은 뭔가 다음에서 SQL Server2005 년,하지만 제가 관심이 있을 것보고 기타의 더 많은 불가지론 방법:

WITH Ordered AS (
SELECT ROW_NUMBER() OVER (ORDER BY OrderID) AS RowNumber, OrderID, OrderDate
FROM Orders)
SELECT *
FROM Ordered
WHERE RowNumber = 1000000

신용 위 SQL: Firoz 안사리의 Weblog

업데이트:Troels Arvin 의 응답 에 대한 SQL 표준입니다. Troels,당신은 어떤 링크도 우리가 인용 할 수있다?

도움이 되었습니까?

해결책

의 방법이 있다고 이에서 선택적 부분은 표준,그러나 많은 데이터베이스의 자신의 방법을 지원 하고 있습니다.

정말 좋은 사이트는 이것에 대해 이야기와 다른 것들입니다 http://troels.arvin.dk/db/rdbms/#select-limit.

기본적으로,PostgreSQL and MySQL 지원하는 비영 표준:

SELECT...
LIMIT y OFFSET x 

Oracle,DB2 및 MSSQL 지원 표준 윈도우 기능:

SELECT * FROM (
  SELECT
    ROW_NUMBER() OVER (ORDER BY key ASC) AS rownumber,
    columns
  FROM tablename
) AS foo
WHERE rownumber <= n

(나가사 사이트에서 링크된 때문에 위에 나는 사용하지 않는 그 DBs)

업데이트: 로 PostgreSQL8.4 표준 윈도우 기능이 지원되는,그래서 기대하는 두 번째 예는 작업에 대한 PostgreSQL 니다.

업데이트: SQLite 추가 창이 기능 지원 버전 3.25.0 에 2018-09-15 그래서 두 형태에서 작동 SQLite.

다른 팁

LIMIT / OFFSET 구문에 PostgreSQL 입니다:

SELECT
    *
FROM
    mytable
ORDER BY
    somefield
LIMIT 1 OFFSET 20;

이 예제를 선택 21 니다. OFFSET 20 말레스를 건너뛰고 처음 20 다.지정하지 않는 경우에는 ORDER BY 절을 보장이 없다는 기록을 당신은 다시 얻을 수있는,거의 유용합니다.

분명히 SQL 표준은 침묵하는 제한에 문제를 외부의 윈도우 기능 이유입니다,모든 사람을 구현합니다.

이지 않았어요 어떤 나머지는,하지만 내가 아는 SQLite 및 MySQL 없는"기본"행습니다.그 사이에 두 개의 방언에는 적어도 다음의 조각을 잡고 15 항목에서 the_table 분류,날짜/시간이 추가되었:

SELECT * FROM the_table ORDER BY added DESC LIMIT 1,15

(물론,할 필요가 있는 날짜 필드를 추가했고,그것을 설정하는 날짜/시간는 항목을 추가...)

SQL2005 고 위에는 이 기능이 내장되어 있습니다.를 사용하여 그룹()함수입니다.그것은 우수를 위한 웹 페이지의 << 이전 다음>>식 검색:

Syntax:

SELECT
    *
FROM
    (
        SELECT
            ROW_NUMBER () OVER (ORDER BY MyColumnToOrderBy) AS RowNum,
            *
        FROM
            Table_1
    ) sub
WHERE
    RowNum = 23

나이 격렬하게 비효율적이지만 매우 간단한 접근 방식에 근무하는 작은 데이터 집합하는 내가 그것을 시도했다.

select top 1 field
from table
where field in (select top 5 field from table order by field asc)
order by field desc

이 5 항목을 변경,두 번째는 최고 번호를 얻을 다른 n 번째 항목

SQL 서버(I think)이지만 작동에 이전 버전은 지원하지 않는 그룹().

지 확인에 SQL Server:

Select top 10 * From emp 
EXCEPT
Select top 9 * From emp

이것은 당신에게 10 의 행 emp 니다.

1 작은 변경:n-1 대신 n.

select *
from thetable
limit n-1, 1

반대로 무엇을 어떤 답변의 요구,SQL 표준하지 않은 침묵이 주제에 관한.

이 SQL:2003 를 사용할 수 있게 되었습"기능"를 건너뛰고 행과 제한 결과를 설정합니다.

에서 SQL:2008 년,약간 더 간단한 방법이 추가 되었습,사용
OFFSET 건너뛰기 ROWS FETCH FIRST n ROWS ONLY

개인적으로,나는 생각하지 않는 SQL:2008 의 추가 정말 필요한 경우 그래서 나는 ISO,나는 그것을 유지는 이미 오히려 큰 표준입니다.

Oracle:

select * from (select foo from bar order by foo) where ROWNUM = x

때 우리는 작업에 MSSQL2000,우리가 무엇을 우리는"라는 트리플 플립":

편집

DECLARE @InnerPageSize int
DECLARE @OuterPageSize int
DECLARE @Count int

SELECT @Count = COUNT(<column>) FROM <TABLE>
SET @InnerPageSize = @PageNum * @PageSize
SET @OuterPageSize = @Count - ((@PageNum - 1) * @PageSize)

IF (@OuterPageSize < 0)
    SET @OuterPageSize = 0
ELSE IF (@OuterPageSize > @PageSize)
    SET @OuterPageSize = @PageSize

DECLARE @sql NVARCHAR(8000)

SET @sql = 'SELECT * FROM
(
    SELECT TOP ' + CAST(@OuterPageSize AS nvarchar(5)) + ' * FROM
    (
        SELECT TOP ' + CAST(@InnerPageSize AS nvarchar(5)) + ' * FROM <TABLE> ORDER BY <column> ASC
    ) AS t1 ORDER BY <column> DESC
) AS t2 ORDER BY <column> ASC'

PRINT @sql
EXECUTE sp_executesql @sql

지 않은 우아하지 않았는 빠른하지만,일했다.

SQL SERVER


선택 n'번째 레코드에서 최고

SELECT * FROM (
SELECT 
ID, NAME, ROW_NUMBER() OVER(ORDER BY ID) AS ROW
FROM TABLE 
) AS TMP 
WHERE ROW = n

선택 n'번째 레코드에서 하단

SELECT * FROM (
SELECT 
ID, NAME, ROW_NUMBER() OVER(ORDER BY ID DESC) AS ROW
FROM TABLE 
) AS TMP 
WHERE ROW = n

여기에 빠른 솔루션의 혼란이 있습니다.

SELECT * FROM table ORDER BY `id` DESC LIMIT N, 1

여기에서 얻을 수 있습니다 마지막 행으로 채우는 N=0,두 번째에 의해 마지막 N=1,네 번째 마지막으로 채우는 N=3 니다.

이것은 매우 일반적인 질문 인터뷰를 통해 그리고 이것은 매우 간단하 ans 습니다.

추가하려면 금액,ID 또는 일부 숫자 정렬 순서를 확보할 수 있습에 대한 이동 주는 기능에 MySQL.

SELECT DISTINCT (`amount`) FROM cart ORDER BY CAST( `amount` AS SIGNED ) DESC LIMIT 4 , 1

여기에 작성하여 N=4 당신을 얻을 수있을 것입니다 지난 다섯 번째 레코드의 가장 높은 금액을 장바구니에서 테이블.할 수 있습 맞는 당신의 분야와 테이블은 이름을 가지고 올 솔루션입니다.

ADD:

LIMIT n,1

는 결과를 제한 하나의 결과에서 시작하는 결과 n.

예를 들어,을 선택하려면 모든 10 행 MSSQL 사용할 수 있습니다;

SELECT * FROM (
  SELECT
    ROW_NUMBER() OVER (ORDER BY ColumnName1 ASC) AS rownumber, ColumnName1, ColumnName2
  FROM TableName
) AS foo
WHERE rownumber % 10 = 0

그냥드 번호를 변경 10 여기에는 어떤 수를 당하고 싶습니다.

제 n,1 에서 작동하지 않 MS SQL Server.나는 그것이 단지에 대한 유일한 주요 데이터베이스를 지원하지 않는다는 구문을 사용합니다.공정하게,그렇지 않은 부분의 SQL 표준이지만,그것은 그렇게 널리는 것을 지원해야 합니다.에서 제외한 모든 SQL 서버 제한을 작동합니다.에 대한 SQL 서버지 않았을 찾을 수있는 우아한 솔루션입니다.

여기에 일반 버전의 sproc 나는 최근에 쓴 Oracle 할 수 있는 동적 페이징/sorting-HTH

-- p_LowerBound = first row # in the returned set; if second page of 10 rows,
--                this would be 11 (-1 for unbounded/not set)
-- p_UpperBound = last row # in the returned set; if second page of 10 rows,
--                this would be 20 (-1 for unbounded/not set)

OPEN o_Cursor FOR
SELECT * FROM (
SELECT
    Column1,
    Column2
    rownum AS rn
FROM
(
    SELECT
        tbl.Column1,
        tbl.column2
    FROM MyTable tbl
    WHERE
        tbl.Column1 = p_PKParam OR
        tbl.Column1 = -1
    ORDER BY
        DECODE(p_sortOrder, 'A', DECODE(p_sortColumn, 1, Column1, 'X'),'X'),
        DECODE(p_sortOrder, 'D', DECODE(p_sortColumn, 1, Column1, 'X'),'X') DESC,
        DECODE(p_sortOrder, 'A', DECODE(p_sortColumn, 2, Column2, sysdate),sysdate),
        DECODE(p_sortOrder, 'D', DECODE(p_sortColumn, 2, Column2, sysdate),sysdate) DESC
))
WHERE
    (rn >= p_lowerBound OR p_lowerBound = -1) AND
    (rn <= p_upperBound OR p_upperBound = -1);

하지만 정말,지 않는 모든이 정말 술수를 위해 좋은 데이터베이스를 디자인에서 첫 번째 장소는?몇 시간이 나는 데 필요한 기능은 다음과 같이 그것에 대한 간단한 오프 쿼리 만 빠른 보고서입니다.을 위해 실제 작업을 사용하여,이들 간이 초대하는 문제입니다.선택하는 경우 특정 행는 데 필요한 그만이 열을 순차적 가치와 수행합니다.

Oracle12c 를 사용할 수 있습니다 OFFSET..FETCH..ROWS 옵션 ORDER BY

예를 들어 3 번째 레코드에서 최고:

SELECT * 
FROM   sometable
ORDER BY column_name
OFFSET 2 ROWS FETCH NEXT 1 ROWS ONLY;

에 Sybase SQL Anywhere:

SELECT TOP 1 START AT n * from table ORDER BY whatever

잊지 않기 위해 또는 그것의 의미가 없습니다.

T-SQL-선 N 번째호에서 테이블

select * from
 (select row_number() over (order by Rand() desc) as Rno,* from TableName) T where T.Rno = RecordNumber

Where  RecordNumber --> Record Number to Select
       TableName --> To be Replaced with your Table Name

예를 들어,선택하려 5 번째 레코드 테이블에서 직원,당신의 질문은 아래와 같아야 한다

select * from
 (select row_number() over (order by Rand() desc) as Rno,* from Employee) T where T.Rno = 5
SELECT * FROM emp a
WHERE  n = (SELECT COUNT( _rowid)
              FROM emp b
             WHERE a. _rowid >= b. _rowid);
SELECT
    top 1 *
FROM
    table_name
WHERE
    column_name IN (
        SELECT
            top N column_name
        FROM
            TABLE
        ORDER BY
            column_name
    )
ORDER BY
    column_name DESC

나는 이에 대한 쿼리를 찾는 Nth 니다.예를 이 쿼리할

SELECT
    top 1 *
FROM
    Employee
WHERE
    emp_id IN (
        SELECT
            top 7 emp_id
        FROM
            Employee
        ORDER BY
            emp_id
    )
ORDER BY
    emp_id DESC

에 대한 SQL Server,일반적인 방법으로 이동하여 행 번호가 이와 같:

SET ROWCOUNT @row --@row = the row number you wish to work on.

예를 들어:

set rowcount 20   --sets row to 20th row

select meat, cheese from dbo.sandwich --select columns from table at 20th row

set rowcount 0   --sets rowcount back to all rows

이것은 20 줄의 정보입니다.해야에 넣어 rowcount0 다.

믿는 당신이 찾을 수 있습니다 SQL 엔진이 실행하는 이는 하나...

WITH sentence AS
(SELECT 
    stuff,
    row = ROW_NUMBER() OVER (ORDER BY Id)
FROM 
    SentenceType
    )
SELECT
    sen.stuff
FROM sentence sen
WHERE sen.row = (ABS(CHECKSUM(NEWID())) % 100) + 1

Nothing fancy,특별한 기능을 사용하는 경우 캐시 나처럼...

SELECT TOP 1 * FROM (
  SELECT TOP n * FROM <table>
  ORDER BY ID Desc
)
ORDER BY ID ASC

는 당신의 ID 열 또는 날짜 스탬프 열 수 있습니다.

이 방법이다 나는 그것을 할 거라고 내 DB2SQL,나는 은 주민등록번호(상대 기록 번호)가 내에 저장된 테이블에 의하여 O/S;

SELECT * FROM (                        
   SELECT RRN(FOO) AS RRN, FOO.*
   FROM FOO                         
   ORDER BY RRN(FOO)) BAR             
 WHERE BAR.RRN = recordnumber
select * from 
(select * from ordered order by order_id limit 100) x order by 
x.order_id desc limit 1;

먼저 선택 최 100 행로에서 주문 오름차순으로 선택한 다음 마지막 행에 의해 주문을 내림차순으로 제한 1.그러나 이것은 매우 비싼 문으로 데이터에 액세스하다.

그것은 나에게 있어야 할 것이 효율적이,당신은 1)생성하는 무작위 숫자 0 과 하나의 숫자 이상의 데이터베이스 기록,그리고 2)선택할 수 있게 행할 수 있습니다.불행하게도,다른 데이터베이스가 서로 다른 임의의 번호 발생기 및 다른 방법을 선택하려면에서 연속으로서 위치를 결정 일반적으로 지정하는 얼마나 많은 행를 건너와 당신은 얼마나 많은 행고 싶지만,그것은 다른 다른 데이터베이스가 있습니다.여기에는 뭔가가 나를 위해서 SQLite:

select * 
from Table 
limit abs(random()) % (select count(*) from Words), 1;

그것은에 의존해 사용할 수 있는 하위에서 제한 조항(에 SQLite 은 제한 <recs to="" skip="">,<recs to="" take="">)선수의 기록에서 테이블,특히 효율적의 일부가되는 데이터베이스의 메타데이터,그에 따라 달라지는 데이터베이스의 구현합니다.또한,내가 알지 못하는 경우 쿼리가 실제로 구축한 결과를 설정하기 전에 검색 N 기록은,하지만 내가 바라는 것은 그것이 필요하지 않습니다.참고하는 내가 지정하지 않는다는"주여"절이 있습니다.그것이 더 좋을 수 있습하는"주"에 의해 무언가가 다음과 같은 기본 키가 있는 지수 점점 N 번째 레코드 인덱스에서 빠를 수 있는 경우에 데이터베이스를 얻을 수 없습 N 번째 레코드 데이터베이스에서 자체 구축하지 않고 결과를 설정합니다.

에 대한 SQL 서버는 다음과 같은 반환됩니다 첫 번째 행에서 주는 테이블.

declare @rowNumber int = 1;
    select TOP(@rowNumber) * from [dbo].[someTable];
EXCEPT
    select TOP(@rowNumber - 1) * from [dbo].[someTable];

할 수 있습 루프를 통해 값으로 무언가 이것을 좋아한다:

WHILE @constVar > 0
BEGIN
    declare @rowNumber int = @consVar;
       select TOP(@rowNumber) * from [dbo].[someTable];
    EXCEPT
       select TOP(@rowNumber - 1) * from [dbo].[someTable];  

       SET @constVar = @constVar - 1;    
END;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top