【问题标题】:Select newest version from table (MS SQL Server, SQLite)从表中选择最新版本(MS SQL Server、SQLite)
【发布时间】:2015-12-04 10:47:43
【问题描述】:

比方说,我有下表:

ID | UID | Version | Content
---+-----+---------+-----------------------------
 1 |   1 |       1 | Something
 2 |   1 |       2 | Something (changed)
 3 |   2 |       1 | Alice has a cat
 4 |   2 |       2 | Alice has a cat and a dog
 5 |   2 |       3 | Alice has a cat and a canary

我需要创建查询,它将返回所有对象,但仅限于最新版本,所以在这种情况下:

ID | UID | Version | Content
---+-----+---------+-----------------------------
 2 |   1 |       2 | Something (changed)
 5 |   2 |       3 | Alice has a cat and a canary

由于 SQL 方言不同,我将在 MS Sql Server 2008 和 SQLite 3 上运行此查询。

我怎样才能做到这一点?

【问题讨论】:

    标签: sql sql-server sqlite


    【解决方案1】:

    NOT EXISTS查询:

    select *
    from tablename t1
    where not exists (select 1 from tablename t2
                      where t2.uid = t1.uid
                        and t2.version > t1.version)
    

    JOIN查询:

    select t1.*
    from tablename t1
        join (select uid, max(version) as version from tablename group by uid) t2
        on t2.uid = t1.uid and t2.version = t1.version
    

    相关子查询:

    select t1.*
    from tablename t1
    where t1.version = (select max(version) from tablename t2
                        where t2.uid = t1.uid)
    

    IN子查询:

    select *
    from tablename
    where (uid, version) IN (select uid, max(version) from tablename
                             group by uid)
    

    【讨论】:

      【解决方案2】:

      有几种不同的方法可以解决这个问题。但每种方法都遵循相同的原则。

      查询的一部分将标识每个 UID 的最新版本。这将用于过滤记录集。

      在下面的示例中,我使用子查询找到了每个 UID 的当前版本,然后我用它来过滤主记录集。

      Example

      /* This table gives us some sample records
       * to experiment with.
       */
      DECLARE @Example TABLE
          (
              ID            INT                PRIMARY KEY,
              [UID]        INT                NOT NULL,
              [Version]    INT                NOT NULL,
              Content        VARCHAR(255)    NOT NULL
          )
      ;
      
      /* Populate the sample data.
       */
      INSERT INTO @Example
          (
              ID,
              [UID],
              [Version],
              Content
          )
      VALUES
          (1, 1, 1, 'Something'),
          (2, 1, 2, 'Something (changed)'),
          (3, 2, 1, 'Alice has a cat'),
          (4, 2, 2, 'Alice has a cat and a dog'),
          (5, 2, 3, 'Alice has a cat and a canary')
      ;
      
      /* Return the most recent version of each UID.
       * This is done by using a sub query to calcualte the max of each UIDs version.
       */
      SELECT
          e.*
      FROM
          @Example AS e
              INNER JOIN
                  (    
                      /* This sub query finds the max version of
                       * each UID.
                       */
                      SELECT
                          [UID],
                          MAX([Version]) AS Current_Version
                      FROM
                          @Example    
                      GROUP BY
                          [UID]
                  ) AS mv
              ON    mv.[UID]            = e.[UID]
              AND    mv.Current_Version    = e.[Version]
      ;
      

      【讨论】:

        猜你喜欢
        • 2015-09-07
        • 2010-11-29
        • 1970-01-01
        • 2019-02-11
        • 1970-01-01
        • 2021-12-02
        • 2022-06-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多