2

我想从数据库中检索所有行,其中1OWNERKEY但只有DATAVERSION.DATACONTROLID

在下面的示例中,我有两行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)以某种方式使用,但是要分组呢?我可以同时使用*andMAX吗?

4

3 回答 3

2

GROUP BY这是一个使用in的简单示例MSSQL

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确定“不同”记录并且DATAVERSION是记录的实例。

这将对DATACONTROLIDMAX(DATAVERSION)进行分组并返回分组结果。在这种情况下,DATACONTROLID = 1has DATAVERSION = 1 and 2,因此返回 2。

值得注意的是,如果您想在结果中看到其他列并且它们不是聚合,例如MAX(),那么您需要将它们添加到GROUP BY子句中 - 就像我在这里对OWNERKEY列所做的那样。如果您尝试在 中SELECT OWNERKEY不包含它GROUP BY,您将收到错误消息。

编辑:

这是使用 a 完成相同结果的更好方法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这样做的目的是将我之前向您展示的相同语句转换为过滤表。该INNER JOIN部分正在选择它所属的MAX(DATAVERSION)和它,并将结果作为临时表返回。DATACONTROLIDmdb2

这个新的内表将返回以下内容:

DATAVERSION DATACONTROLID
2           1
1           2
1           3

然后我们获取该结果并获取所有(SELECT *)符合此条件的行。由于此内部表不包含 的结果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

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

于 2015-11-24T17:54:40.170 回答
2

尝试这个:

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

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

于 2015-11-24T17:19:26.883 回答
0

怎么样

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

这适用于某些数据库环境;我希望你的!我从 Rick F. van der Lans 的“SQL 简介,掌握关系数据库语言”中了解到这一点。很容易阅读。

于 2015-11-24T17:25:32.160 回答