Select 所有行,但只有数据库中的最新(最高)版本

Select all rows but only the latest (highest) version from database

我想从数据库中检索 OWNERKEY 为 1 的所有行,但只检索 DATACONTROLID 中最高的 DATAVERSION

在下面的示例中,我有两行 DATACONTROLID= 1,它们的 1 和 2 为 DATAVERSION。我要最高的。

我的数据库:

DATAKEY       OWNERKEY       OWNERTYPE      DATAVERSION   MALLKEY       DATAVALUE    DATAVALUETYPE   DATACONTROLID   DATADATE     DATATIME      DATASIGN
===========   ============   ===========   ===========   ===========   =========    ============    =============   ==========   ===========   =========     
4              1             2             1             1             1             2                1             2015-11-24   09:55:00:00   ADMIN
3              1             2             2             1             2             2                1             2015-11-23   20:55:00:00   ADMIN
2              1             2             1             1             3             2                2             2015-11-23   15:39:00:00   ADMIN
1              1             2             1             1             4             2                3             2015-11-23   11:29:00:00   ADMIN

想要的结果:

DATAKEY       OWNERKEY       OWNERTYPE      DATAVERSION   MALLKEY       DATAVALUE    DATAVALUETYPE   DATACONTROLID   DATADATE     DATATIME      DATASIGN
===========   ============   ===========   ===========   ===========   =========    ============    =============   ==========   ===========   =========     
3              1             2             2             1             2             2                1             2015-11-23   20:55:00:00   ADMIN
2              1             2             1             1             3             2                2             2015-11-23   15:39:00:00   ADMIN
1              1             2             1             1             4             2                3             2015-11-23   11:29:00:00   ADMIN

我从哪里开始?

SELECT *
FROM MyDB
WHERE OWNERKEY = 1

上面的陈述是显而易见的部分,但我该如何从那开始?

我想我应该以某种方式使用 MAX(DATAVERSION),但是要根据什么进行分组?我可以同时使用 *MAX 吗?

试试这个:

SELECT *
  FROM (SELECT OWNERKEY,DATACONTROLID,DATAVERSION,
               rank() over (partition by DATACONTROLID order by DATAVERSION desc) rnk
          FROM MyDB WHERE OWNERKEY = 1)
 WHERE rnk = 1;

注意:我还没有测试过,但这应该可以工作

怎么样

SELECT *
FROM MyDB
WHERE OWNERKEY = 1
and   DATAVERSION = 
      (SELECT max(DATAVERSION)
      FROM MyDB
      WHERE OWNERKEY = 1)

在某些数据库环境中有效;我希望你的!我从 Rick F. van der Lans 的 "Introduction to SQL, Mastering the Relational Database Language" 那里了解到这一点。非常容易阅读。

这是一个在 MSSQL 中使用 GROUP BY 的简单示例:

SELECT  DATACONTROLID, 
        MAX(DATAVERSION) AS DATAVERSION, -- Note that 'AS' just gives the column a name in the result set, this isn't required.
        OWNERKEY
FROM    MyDB
WHERE   OWNERKEY = 1
GROUP BY DATACONTROLID, OWNERKEY

这是假设 DATACONTROLID 确定 'distinct' 条记录并且 DATAVERSION 是记录的实例。

这将对 DATACONTROLID 列和 return 分组结果 MAX(DATAVERSION) 进行分组。在这种情况下,DATACONTROLID = 1DATAVERSION = 1 and 2,所以这个 returns 2.

值得注意的是,如果您想在结果中看到更多的列 并且它们不是 MAX() 等聚合,那么您需要添加它们添加到 GROUP BY 子句 - 正如我在此处对 OWNERKEY 列所做的那样。如果您尝试 SELECT OWNERKEYGROUP BY 中没有它,您将收到错误消息。

编辑:

这是使用 JOIN:

实现相同结果的更好方法
SELECT  *
FROM    MyDB mdb
INNER JOIN (
    SELECT  MAX(DATAVERSION) AS DATAVERSION,
            DATACONTROLID
    FROM    MyDB
    WHERE   OWNERKEY = 1
    GROUP BY DATACONTROLID
) AS mdb2 
    ON  mdb2.DATACONTROLID = mdb.DATACONTROLID 
        AND mdb2.DATAVERSION = mdb.DATAVERSION

这样做是将我之前向您展示的相同 GROUP BY 语句转换为过滤 table。 INNER JOIN 部分正在选择 MAX(DATAVERSION) 和它所属的 DATACONTROLID,然后 return 将结果作为临时 table mdb2

这个新的内部 table 将 return 以下内容:

DATAVERSION DATACONTROLID
2           1
1           2
1           3

然后我们获取该结果并获取所有符合此条件的行 (SELECT *)。由于此内部 table 不包含 DATAVERSION = 1 where DATACONTROLID = 1 的结果,因此该行被过滤掉。

相反,如果您只想查看 较旧的 版本而不是最新版本,则可以将此条件更改为 LEFT OUTER JOIN 并添加 WHERE mdb2.DATAVERSION IS NULL

SELECT  *
FROM    MyDB mdb
LEFT OUTER JOIN (
    SELECT  MAX(DATAVERSION) AS DATAVERSION,
            DATACONTROLID
    FROM    MyDB
    WHERE   OWNERKEY = 1
    GROUP BY DATACONTROLID
) AS mdb2 
    ON  mdb2.DATACONTROLID = mdb.DATACONTROLID 
        AND mdb2.DATAVERSION = mdb.DATAVERSION
WHERE mdb2.DATAVERSION IS NULL

由于我们在 mdb2 中选择了 MAX(DATAVERSION),因此对于不符合此条件的行,它将包含空值。