我希望从OWNERKEY为1的DB中检索所有行,但只检索DATACONTROLID的最高行。
在下面的示例中,我有两个行,其中DATACONTROLID= 1,它们有1和2作为DATAVERSION。我想得到最高的。
MyDB:
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吗?
发布于 2015-11-24 17:54:40
下面是一个在GROUP BY中使用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是记录的实例。
这将对DATACONTROLID列进行分组,并返回分组结果的MAX(DATAVERSION)。在本例中,DATACONTROLID = 1有DATAVERSION = 1 and 2,因此返回2。
值得注意的是,如果您希望在结果中看到更多的列,并且它们不是聚合类的,那么您需要将它们添加到GROUP BY子句中--就像我在这里对OWNERKEY列所做的那样。如果您尝试SELECT OWNERKEY而没有将它包含在GROUP 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语句转换为一个筛选表。INNER JOIN部分选择它所属的MAX(DATAVERSION)和DATACONTROLID,并将结果作为临时表mdb2返回。
这个新的内表将返回以下内容:
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)中选择了mdb2,因此它将包含不符合此条件的行的null。
发布于 2015-11-24 17:19:26
试试这个:
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-24 17:25:32
怎么样
SELECT *
FROM MyDB
WHERE OWNERKEY = 1
and DATAVERSION =
(SELECT max(DATAVERSION)
FROM MyDB
WHERE OWNERKEY = 1)它适用于某些数据库环境,我希望您的!我从RickF.vanderLans的“SQL简介,掌握关系数据库语言”中了解到这一点。很容易读懂。
https://stackoverflow.com/questions/33899707
复制相似问题