복붙노트

[SQL] 각 그룹의 상위 1 행을 가져 오기

SQL

각 그룹의 상위 1 행을 가져 오기

나는 각 그룹에 대한 최신 항목을 얻으려면 테이블을 가지고있다. 다음 표는 다음과 같습니다

DocumentStatusLogs 표

|ID| DocumentID | Status | DateCreated |
| 2| 1          | S1     | 7/29/2011   |
| 3| 1          | S2     | 7/30/2011   |
| 6| 1          | S1     | 8/02/2011   |
| 1| 2          | S1     | 7/28/2011   |
| 4| 2          | S2     | 7/30/2011   |
| 5| 2          | S3     | 8/01/2011   |
| 6| 3          | S1     | 8/02/2011   |

표는 DocumentID별로 그룹화 및 내림차순으로 DateCreated에 의해 정렬됩니다. 각 DocumentID, 나는 최신 상태를 싶어.

나의 선호 출력 :

| DocumentID | Status | DateCreated |
| 1          | S1     | 8/02/2011   |
| 2          | S3     | 8/01/2011   |
| 3          | S1     | 8/02/2011   |

자세한 내용은 부모 테이블을 참조하십시오 :

현재 문서 표

| DocumentID | Title  | Content  | DateCreated |
| 1          | TitleA | ...      | ...         |
| 2          | TitleB | ...      | ...         |
| 3          | TitleC | ...      | ...         |

부모 테이블 내가 쉽게 상태를 액세스 할 수있는이과 같이해야 하는가?

| DocumentID | Title  | Content  | DateCreated | CurrentStatus |
| 1          | TitleA | ...      | ...         | s1            |
| 2          | TitleB | ...      | ...         | s3            |
| 3          | TitleC | ...      | ...         | s1            |

최신 정보 난 그냥 쉽게 이러한 문제를 해결 할 수있는 "적용"을 사용하는 방법을 배웠습니다.

해결법

  1. ==============================

    1.

    ;WITH cte AS
    (
       SELECT *,
             ROW_NUMBER() OVER (PARTITION BY DocumentID ORDER BY DateCreated DESC) AS rn
       FROM DocumentStatusLogs
    )
    SELECT *
    FROM cte
    WHERE rn = 1
    

    당신은 하루에 2 개 항목을 기대한다면,이 임의로 하나를 선택합니다. 하루 두 항목을 얻으려면, 대신 DENSE_RANK를 사용

    정규화에 대한 여부를 당신이 원한다면, 그것은 의존한다 :

    약자로, 당신은 상태 기록을 보존 할 수 있습니다. 당신이 (denormalisation 인)도 부모 테이블에서 최신 상태를 원하는 경우에 당신은 부모의 "상태"를 유지하기 위해 트리거를 필요 했어. 또는이 상태 기록 테이블을 놓습니다.

  2. ==============================

    2.난 그냥 교차 사용에 적용하는 방법을 배웠습니다. 다음은이 시나리오에서 그것을 사용하는 방법은 다음과 같습니다

    난 그냥 교차 사용에 적용하는 방법을 배웠습니다. 다음은이 시나리오에서 그것을 사용하는 방법은 다음과 같습니다

     select d.DocumentID, ds.Status, ds.DateCreated 
     from Documents as d 
     cross apply 
         (select top 1 Status, DateCreated
          from DocumentStatusLogs 
          where DocumentID = d.DocumentId
          order by DateCreated desc) as ds
    
  3. ==============================

    3.테이블과를 사용하여,이 테스트는 2008 R2 SQL 서버에 대해 실행 된 적용 나는 여기에 다양한 권고를 통해 어떤 타이밍 짓을했는지, 그 결과는 정말 관련된 테이블의 크기에 달려 있지만, 가장 일관된 솔루션은 CROSS을 사용하고 있습니다 137000000 개 기록과 6,500 기록하고, 다른 (동일한 스키마). 조회되는 열은 테이블 기본 키의 일부이며, 테이블 폭 (30 바이트에 대해) 매우 작다. 시간은 실제 실행 계획에서 SQL Server가보고됩니다.

    테이블과를 사용하여,이 테스트는 2008 R2 SQL 서버에 대해 실행 된 적용 나는 여기에 다양한 권고를 통해 어떤 타이밍 짓을했는지, 그 결과는 정말 관련된 테이블의 크기에 달려 있지만, 가장 일관된 솔루션은 CROSS을 사용하고 있습니다 137000000 개 기록과 6,500 기록하고, 다른 (동일한 스키마). 조회되는 열은 테이블 기본 키의 일부이며, 테이블 폭 (30 바이트에 대해) 매우 작다. 시간은 실제 실행 계획에서 SQL Server가보고됩니다.

    Query                                  Time for 6500 (ms)    Time for 137M(ms)
    
    CROSS APPLY                                    17.9                17.9
    SELECT WHERE col = (SELECT MAX(COL)…)           6.6               854.4
    DENSE_RANK() OVER PARTITION                     6.6               907.1
    

    나는 정말 놀라운 일이 십자가에 관계없이 포함 된 행 수의 적용에 대한 시간이 얼마나 일치했다 생각합니다.

  4. ==============================

    4.나는 이것이 옛 스레드이지만 TIES 솔루션과 상위 1은 아주 좋은 및 솔루션을 통해 일부 읽기에 도움이 될 수 알고있다.

    나는 이것이 옛 스레드이지만 TIES 솔루션과 상위 1은 아주 좋은 및 솔루션을 통해 일부 읽기에 도움이 될 수 알고있다.

    select top 1 with ties
       DocumentID
      ,Status
      ,DateCreated
    from DocumentStatusLogs
    order by row_number() over (partition by DocumentID order by DateCreated desc)
    

    더 TOP 절에 대해 여기에서 찾을 수 있습니다.

  5. ==============================

    5.

    SELECT * FROM
    DocumentStatusLogs JOIN (
      SELECT DocumentID, MAX(DateCreated) DateCreated
      FROM DocumentStatusLogs
      GROUP BY DocumentID
      ) max_date USING (DocumentID, DateCreated)
    

    어떤 데이터베이스 서버? 이 코드는 모두 작동하지 않습니다.

    질문의 두 번째 절반에 관해서는, 열로 상태를 포함하는 나에게 합리적인 것 같다. 당신은 로그로 DocumentStatusLogs을 떠나지 만, 여전히 기본 테이블의 최신 정보를 저장할 수 있습니다.

    BTW, 당신은 이미 (한 DateCreated가 DocumentStatusLogs에서 고유로) 당신이 단지를 사용하여 DocumentStatusLogs에 가입 할 수있는 문서 테이블에서 DateCreated 열이있는 경우.

    편집 : MSSQL 너무로 변경, 사용을 지원하지 않습니다 :

    ON DocumentStatusLogs.DocumentID = max_date.DocumentID AND DocumentStatusLogs.DateCreated = max_date.DateCreated
    
  6. ==============================

    6.성능에 대해 걱정하는 경우, 당신은 또한 MAX ()와 함께이 작업을 수행 할 수 있습니다

    성능에 대해 걱정하는 경우, 당신은 또한 MAX ()와 함께이 작업을 수행 할 수 있습니다

    SELECT *
    FROM DocumentStatusLogs D
    WHERE DateCreated = (SELECT MAX(DateCreated) FROM DocumentStatusLogs WHERE ID = D.ID)
    

    MAX하지 않는 반면, ROW_NUMBER ()는 당신의 SELECT 문에서 행 모든 정렬을 필요로한다. 크게 쿼리 속도를해야합니다.

  7. ==============================

    7.이것은 아주 오래된 스레드,하지만 난 허용 대답은 나를 위해 특히 잘 작동하지 않았다 나는 그냥 같은 내 두 센트를 던질 거라고 생각했다. 나는 (> SQL 서버 2012 년 500 만 개 플러스 기록 45 초)으로 큰 데이터 세트에 GBN의 솔루션을 시도하고 몹시 느린 발견했다. 실행 계획을 보면이 문제가 크게 일을 느리게 정렬 작업이 필요하다는 것을 분명하다.

    이것은 아주 오래된 스레드,하지만 난 허용 대답은 나를 위해 특히 잘 작동하지 않았다 나는 그냥 같은 내 두 센트를 던질 거라고 생각했다. 나는 (> SQL 서버 2012 년 500 만 개 플러스 기록 45 초)으로 큰 데이터 세트에 GBN의 솔루션을 시도하고 몹시 느린 발견했다. 실행 계획을 보면이 문제가 크게 일을 느리게 정렬 작업이 필요하다는 것을 분명하다.

    여기에 내가 더 정렬 작업이 필요하지 않고 클러스터되지 않은 인덱스 검색을 수행하는 엔티티 프레임 워크에서 해제하는 것이 대안이다. 이는 전술 한 레코드 세트 2초 <의 실행 시간을 아래로 감소시킨다.

    SELECT 
    [Limit1].[DocumentID] AS [DocumentID], 
    [Limit1].[Status] AS [Status], 
    [Limit1].[DateCreated] AS [DateCreated]
    FROM   (SELECT DISTINCT [Extent1].[DocumentID] AS [DocumentID] FROM [dbo].[DocumentStatusLogs] AS [Extent1]) AS [Distinct1]
    OUTER APPLY  (SELECT TOP (1) [Project2].[ID] AS [ID], [Project2].[DocumentID] AS [DocumentID], [Project2].[Status] AS [Status], [Project2].[DateCreated] AS [DateCreated]
        FROM (SELECT 
            [Extent2].[ID] AS [ID], 
            [Extent2].[DocumentID] AS [DocumentID], 
            [Extent2].[Status] AS [Status], 
            [Extent2].[DateCreated] AS [DateCreated]
            FROM [dbo].[DocumentStatusLogs] AS [Extent2]
            WHERE ([Distinct1].[DocumentID] = [Extent2].[DocumentID])
        )  AS [Project2]
        ORDER BY [Project2].[ID] DESC) AS [Limit1]
    

    지금은 완전히 원래의 질문에 지정되지 않은 무언가를 있으리라 믿고있어,하지만 테이블 디자인은 경우 귀하의 ID 열이 자동 증가 ID 것을, 그리고 DateCreated은 그렇다하더라도, 각 삽입에 현재 날짜로 설정 당신이 실제로 (반 실행 시간에 대해) GBN의 솔루션에 상당한 성능 향상을 얻을 수 이상이 동일한 정렬 순서를 제공하고 일종의 빠른입니다으로 DateCreated에 ID 대신 주문에 바로 주문에서 내 쿼리를 실행하지 않고.

  8. ==============================

    8.이것은 내가에 현대적인 답을주고 싶어, 그래서 주제에 가장 쉽게 찾을 질문 중 하나입니다 (내 참조를 위해 도움의 다른 출력에 모두)가 그것. FIRST_VALUE 이상 사용하여 당신은 위의 쿼리의 짧은 작품을 만들 수 있습니다 :

    이것은 내가에 현대적인 답을주고 싶어, 그래서 주제에 가장 쉽게 찾을 질문 중 하나입니다 (내 참조를 위해 도움의 다른 출력에 모두)가 그것. FIRST_VALUE 이상 사용하여 당신은 위의 쿼리의 짧은 작품을 만들 수 있습니다 :

    Select distinct DocumentID
      , first_value(status) over (partition by DocumentID order by DateCreated Desc) as Status
      , first_value(DateCreated) over (partition by DocumentID order by DateCreated Desc) as DateCreated
    From DocumentStatusLogs
    

    이는 SQL Server 2008 및 최대에서 작동합니다. FIRST_VALUE는 이상 절을 사용할 때 선택 톱 1을 달성하는 방법으로 생각 될 수있다. 이상 선택 목록에서 그룹화 그래서 대신 (이렇게 기존의 답변의 많은처럼) 중첩 된 하위 쿼리를 작성 허용, 이것은 더 읽기 방식으로 그것을 않습니다. 도움이 되었기를 바랍니다.

  9. ==============================

    9.내 코드는 각 그룹에서 상위 1을 선택합니다

    내 코드는 각 그룹에서 상위 1을 선택합니다

    select a.* from #DocumentStatusLogs a where 
     datecreated in( select top 1 datecreated from #DocumentStatusLogs b
    where 
    a.documentid = b.documentid
    order by datecreated desc
    )
    
  10. ==============================

    10.위에서 클린트의 멋진 및 정답 확인 :

    위에서 클린트의 멋진 및 정답 확인 :

    두 쿼리 사이의 성능은 아래 흥미 롭다. 52 %는 상부에 존재 하나. 48 %로 두 번째 인. ORDER BY 대신에 DISTINCT를 사용하여 성능에서 4 % 향상. 그러나 ORDER BY 여러 열을 기준으로 정렬 할 수있는 장점이있다.

    IF (OBJECT_ID('tempdb..#DocumentStatusLogs') IS NOT NULL) BEGIN DROP TABLE #DocumentStatusLogs END
    
    CREATE TABLE #DocumentStatusLogs (
        [ID] int NOT NULL,
        [DocumentID] int NOT NULL,
        [Status] varchar(20),
        [DateCreated] datetime
    )
    
    INSERT INTO #DocumentStatusLogs([ID], [DocumentID], [Status], [DateCreated]) VALUES (2, 1, 'S1', '7/29/2011 1:00:00')
    INSERT INTO #DocumentStatusLogs([ID], [DocumentID], [Status], [DateCreated]) VALUES (3, 1, 'S2', '7/30/2011 2:00:00')
    INSERT INTO #DocumentStatusLogs([ID], [DocumentID], [Status], [DateCreated]) VALUES (6, 1, 'S1', '8/02/2011 3:00:00')
    INSERT INTO #DocumentStatusLogs([ID], [DocumentID], [Status], [DateCreated]) VALUES (1, 2, 'S1', '7/28/2011 4:00:00')
    INSERT INTO #DocumentStatusLogs([ID], [DocumentID], [Status], [DateCreated]) VALUES (4, 2, 'S2', '7/30/2011 5:00:00')
    INSERT INTO #DocumentStatusLogs([ID], [DocumentID], [Status], [DateCreated]) VALUES (5, 2, 'S3', '8/01/2011 6:00:00')
    INSERT INTO #DocumentStatusLogs([ID], [DocumentID], [Status], [DateCreated]) VALUES (6, 3, 'S1', '8/02/2011 7:00:00')
    

    옵션 1:

        SELECT
        [Extent1].[ID], 
        [Extent1].[DocumentID],
        [Extent1].[Status], 
        [Extent1].[DateCreated]
    FROM #DocumentStatusLogs AS [Extent1]
        OUTER APPLY (
            SELECT TOP 1
                [Extent2].[ID], 
                [Extent2].[DocumentID],
                [Extent2].[Status], 
                [Extent2].[DateCreated]
            FROM #DocumentStatusLogs AS [Extent2]
            WHERE [Extent1].[DocumentID] = [Extent2].[DocumentID]
            ORDER BY [Extent2].[DateCreated] DESC, [Extent2].[ID] DESC
        ) AS [Project2]
    WHERE ([Project2].[ID] IS NULL OR [Project2].[ID] = [Extent1].[ID])
    

    옵션 2 :

    SELECT 
        [Limit1].[DocumentID] AS [ID], 
        [Limit1].[DocumentID] AS [DocumentID], 
        [Limit1].[Status] AS [Status], 
        [Limit1].[DateCreated] AS [DateCreated]
    FROM (
        SELECT DISTINCT [Extent1].[DocumentID] AS [DocumentID] FROM #DocumentStatusLogs AS [Extent1]
    ) AS [Distinct1]
        OUTER APPLY  (
            SELECT TOP (1) [Project2].[ID] AS [ID], [Project2].[DocumentID] AS [DocumentID], [Project2].[Status] AS [Status], [Project2].[DateCreated] AS [DateCreated]
            FROM (
                SELECT 
                    [Extent2].[ID] AS [ID], 
                    [Extent2].[DocumentID] AS [DocumentID], 
                    [Extent2].[Status] AS [Status], 
                    [Extent2].[DateCreated] AS [DateCreated]
                FROM #DocumentStatusLogs AS [Extent2]
                WHERE [Distinct1].[DocumentID] = [Extent2].[DocumentID]
            )  AS [Project2]
            ORDER BY [Project2].[ID] DESC
        ) AS [Limit1]
    

    M $의 관리 Studio : -> [디스플레이 예상 실행 계획] 강조 표시하고 첫 번째 블록을 실행 한 후, 모두 옵션 1, 옵션 2, 오른쪽 클릭을 강조 표시합니다. 그런 다음 결과를 볼 수있는 모든 일을 실행합니다.

    옵션 1 개 결과 :

    ID  DocumentID  Status  DateCreated
    6   1   S1  8/2/11 3:00
    5   2   S3  8/1/11 6:00
    6   3   S1  8/2/11 7:00
    

    옵션 2 개 결과 :

    ID  DocumentID  Status  DateCreated
    6   1   S1  8/2/11 3:00
    5   2   S3  8/1/11 6:00
    6   3   S1  8/2/11 7:00
    

    노트 :

    또한 피할 내가 끔찍한 실행 계획을 일으키는 원인이 경험 한, WHERE 또는 ON 절에 서브 쿼리 IN / 존재한다. 그러나 주행 거리가 달라집니다. 실행 계획 및 프로필 성능과 필요를 검토!

  11. ==============================

    11.

    SELECT o.*
    FROM `DocumentStatusLogs` o                   
      LEFT JOIN `DocumentStatusLogs` b                   
      ON o.DocumentID = b.DocumentID AND o.DateCreated < b.DateCreated
     WHERE b.DocumentID is NULL ;
    

    당신이 만든 날짜 만 최근 문서 순서를 반환 할 경우, 문서 ID 만 상위 1 문서를 반환합니다

  12. ==============================

    12.

    SELECT doc_id,status,date_created FROM (
    SELECT a.*,Row_Number() OVER(PARTITION BY doc_id ORDER BY date_created DESC ) AS rnk FROM doc a)
    WHERE rnk=1;
    
  13. ==============================

    13.여기 쿼리의 각 색인의 최고의 선택과 함께 손에 문제에 대한 3 개 별도의 접근 방식 (인덱스의 자신을 시도하고 논리적 읽기, 경과 시간, 실행 계획을 참조하십시오. 나는 내 경험에서 제안을 제공하고 있습니다 이 특정 문제에 대한 실행하지 않고 이러한 쿼리).

    여기 쿼리의 각 색인의 최고의 선택과 함께 손에 문제에 대한 3 개 별도의 접근 방식 (인덱스의 자신을 시도하고 논리적 읽기, 경과 시간, 실행 계획을 참조하십시오. 나는 내 경험에서 제안을 제공하고 있습니다 이 특정 문제에 대한 실행하지 않고 이러한 쿼리).

    접근 1 : ROW_NUMBER () 사용. rowstore 지수는 성능을 향상 할 수없는 경우, 당신은 집계 및 그룹화와 쿼리로 서로 다른 열에 의해 모든 시간을 정렬 테이블에 클러스터되지 않은 / 클러스터 columnstore 인덱스를 시도 할 수 columnstore 지수는 일반적으로 최선의 선택이다.

    ;WITH CTE AS
        (
           SELECT   *,
                    RN = ROW_NUMBER() OVER (PARTITION BY DocumentID ORDER BY DateCreated DESC)
           FROM     DocumentStatusLogs
        )
        SELECT  ID      
            ,DocumentID 
            ,Status     
            ,DateCreated
        FROM    CTE
        WHERE   RN = 1;
    

    접근법 2 : FIRST_VALUE 사용. rowstore 지수는 성능을 향상 할 수없는 경우, 당신은 집계 및 그룹화와 쿼리로 서로 다른 열에 의해 모든 시간을 정렬 테이블에 클러스터되지 않은 / 클러스터 columnstore 인덱스를 시도 할 수 columnstore 지수는 일반적으로 최선의 선택이다.

    SELECT  DISTINCT
        ID      = FIRST_VALUE(ID) OVER (PARTITION BY DocumentID ORDER BY DateCreated DESC)
        ,DocumentID
        ,Status     = FIRST_VALUE(Status) OVER (PARTITION BY DocumentID ORDER BY DateCreated DESC)
        ,DateCreated    = FIRST_VALUE(DateCreated) OVER (PARTITION BY DocumentID ORDER BY DateCreated DESC)
    FROM    DocumentStatusLogs;
    

    접근 방법 3 : CROSS APPLY가 사용. 쿼리에 사용되는 열을 포함 DocumentStatusLogs 테이블에 rowstore 인덱스를 생성하기 columnstore 인덱스의 필요없이 쿼리를 커버하기에 충분합니다.

    SELECT  DISTINCT
        ID      = CA.ID
        ,DocumentID = D.DocumentID
        ,Status     = CA.Status 
        ,DateCreated    = CA.DateCreated
    FROM    DocumentStatusLogs D
        CROSS APPLY (
                SELECT  TOP 1 I.*
                FROM    DocumentStatusLogs I
                WHERE   I.DocumentID = D.DocumentID
                ORDER   BY I.DateCreated DESC
                ) CA;
    
  14. ==============================

    14.난 그냥 나 클라이언트에 대한 문제를 해결할 수있는 새로운 오늘 뭔가를 배웠습니다 ....이 게시물을 가로 질러 와서 당신이 만드는 공헌에 대한 여러분 모두 감사드립니다.

    난 그냥 나 클라이언트에 대한 문제를 해결할 수있는 새로운 오늘 뭔가를 배웠습니다 ....이 게시물을 가로 질러 와서 당신이 만드는 공헌에 대한 여러분 모두 감사드립니다.

    CROSS은 나를 위해 일한으로 나는, 내 솔루션에 사용되는 방법이고, 내 고객의 요구에 적용됩니다. 그리고 내가 읽은 것을 자신의 데이터베이스가 실질적으로 증가 할 전망 전반적으로 최상의 성능을 제공한다에서.

    다시 한 번 감사드립니다

  15. ==============================

    15.당신이) (ROW_COUNT를 사용하지 않도록하려는 시나리오에서, 당신은 또한 조인 왼쪽을 사용할 수 있습니다 :

    당신이) (ROW_COUNT를 사용하지 않도록하려는 시나리오에서, 당신은 또한 조인 왼쪽을 사용할 수 있습니다 :

    select ds.DocumentID, ds.Status, ds.DateCreated 
    from DocumentStatusLogs ds
    left join DocumentStatusLogs filter 
        ON ds.DocumentID = filter.DocumentID
        -- Match any row that has another row that was created after it.
        AND ds.DateCreated < filter.DateCreated
    -- then filter out any rows that matched 
    where filter.DocumentID is null 
    

    예 스키마를 들어, 당신은 또한 일반적으로 왼쪽과 같은 출력을 컴파일하는은 "하지 하위 쿼리에"사용할 수 있습니다 가입 :

    select ds.DocumentID, ds.Status, ds.DateCreated 
    from DocumentStatusLogs ds
    WHERE ds.ID NOT IN (
        SELECT filter.ID 
        FROM DocumentStatusLogs filter
        WHERE ds.DocumentID = filter.DocumentID
            AND ds.DateCreated < filter.DateCreated)
    

    참고, 서브 쿼리 패턴 작업 테이블이 경우, 기본 키 "ID"를 적어도 하나의 단일 열 고유 키 / 제약 / 인덱스가 없었하지 않는다면.

    이러한 쿼리는 모두 (쿼리 분석기로 측정)을 ROW_COUNT () 쿼리보다 "비싼"경향이있다. 그들은 빠른 결과를 반환하거나 다른 최적화를 실행 어디 그러나 시나리오가 발생할 수 있습니다.

  16. ==============================

    16.

    SELECT documentid, 
           status, 
           datecreated 
    FROM   documentstatuslogs dlogs 
    WHERE  status = (SELECT status 
                     FROM   documentstatuslogs 
                     WHERE  documentid = dlogs.documentid 
                     ORDER  BY datecreated DESC 
                     LIMIT  1) 
    
  17. ==============================

    17.이 시도:

    이 시도:

    SELECT [DocumentID]
        ,[tmpRez].value('/x[2]', 'varchar(20)') AS [Status]
        ,[tmpRez].value('/x[3]', 'datetime') AS [DateCreated]
    FROM (
        SELECT [DocumentID]
            ,cast('<x>' + max(cast([ID] AS VARCHAR(10)) + '</x><x>' + [Status] + '</x><x>' + cast([DateCreated] AS VARCHAR(20))) + '</x>' AS XML) AS [tmpRez]
        FROM DocumentStatusLogs
        GROUP BY DocumentID
        ) AS [tmpQry]
    
  18. ==============================

    18.이 TSQL 내가 가지고 올 수있는 가장 바닐라이다

    이 TSQL 내가 가지고 올 수있는 가장 바닐라이다

        SELECT * FROM DocumentStatusLogs D1 JOIN
        (
          SELECT
            DocumentID,MAX(DateCreated) AS MaxDate
          FROM
            DocumentStatusLogs
          GROUP BY
            DocumentID
        ) D2
        ON
          D2.DocumentID=D1.DocumentID
        AND
          D2.MaxDate=D1.DateCreated
    
  19. ==============================

    19.당신이 GROUP BY와 함께 다음과 같은 간단한 쿼리를 사용할 수있는 SQLite는 체크 인

    당신이 GROUP BY와 함께 다음과 같은 간단한 쿼리를 사용할 수있는 SQLite는 체크 인

    SELECT MAX(DateCreated), *
    FROM DocumentStatusLogs
    GROUP BY DocumentID
    

    여기 MAX 도움이 각 그룹에서 DateCreated 최대를 얻을 수 있습니다.

    그러나 MYSQL이되지 동료 *이 최대 DateCreated의 값으로 -columns 않는 것 같습니다 :(

  20. from https://stackoverflow.com/questions/6841605/get-top-1-row-of-each-group by cc-by-sa and MIT license