mar*_*net 2 mysql view group-by greatest-n-per-group
我面临的基本问题是我需要每个项目的最新记录。
一些设置... MySQL 5.6.14。
我需要创建两个视图(因为 MySQL 不允许我在视图中有子查询)。我的第一个查询设置了这样的数据。
select
`inventoryrecords`.`inventoryrecordid` AS `inventoryrecordid`,
`inventoryrecords`.`logicaldeviceid` AS `logicaldeviceid`,
`inventoryrecords`.`passrfid` AS `passrfid`,
`inventoryrecords`.`tagepc` AS `tagepc`,
`inventoryrecords`.`currentstate` AS `currentstate`,
`inventoryrecords`.`statedateutc` AS `statedateutc`,
`inventoryrecords`.`ownerobjectid` AS `ownerobjectid`,
`inventoryrecords`.`ownerobjecttype` AS `ownerobjecttype`
from
`inventoryrecords`
where
1
order by `inventoryrecords`.`statedateutc` desc
Run Code Online (Sandbox Code Playgroud)
然后我可以使用我的“真实”查询将所有内容限制为每个 TagEPC 的最后一条记录。
select
`lastinventoryrecords_step1`.`inventoryrecordid` AS `inventoryrecordid`,
`lastinventoryrecords_step1`.`logicaldeviceid` AS `logicaldeviceid`,
`lastinventoryrecords_step1`.`passrfid` AS `passrfid`,
`lastinventoryrecords_step1`.`tagepc` AS `tagepc`,
`lastinventoryrecords_step1`.`currentstate` AS `currentstate`,
`lastinventoryrecords_step1`.`statedateutc` AS `statedateutc`,
`lastinventoryrecords_step1`.`ownerobjectid` AS `ownerobjectid`,
`lastinventoryrecords_step1`.`ownerobjecttype` AS `ownerobjecttype`
from
`lastinventoryrecords_step1`
group by `lastinventoryrecords_step1`.`tagepc`
order by `lastinventoryrecords_step1`.`statedateutc` desc
Run Code Online (Sandbox Code Playgroud)
当我尝试从“真实”视图中选择 * 时,我没有得到我期望的数据。但是,当我在窗口中使用子查询运行查询时。
select * from (
lastinventoryrecords_step1 )
group by tagepc
order by statedateutc desc
Run Code Online (Sandbox Code Playgroud)
产生不正确的数据,而
select * from (
select
inventoryrecordid,
logicaldeviceid,
passrfid,
tagepc,
currentstate,
statedateutc,
ownerobjectid,
ownerobjecttype
from
inventoryrecords
where
1
order by statedateutc desc ) as t1
group by tagepc
order by statedateutc desc
Run Code Online (Sandbox Code Playgroud)
产生正确的数据。
这到底是怎么回事?我错过了什么?
您以不确定的方式使用 GROUP BY。You GROUP BY tagepc
,但是您期望其他列的值是多少?
MySQL 允许这种查询,但 MySQL 从组中任意选择一行。实际上,它往往是组中的第一行,因为它们是物理存储的。
但是在您通过视图查询的情况下,视图将其结果存储在临时表中,其物理顺序可能与原始表中的数据不同。
请注意,http : //dev.mysql.com/doc/refman/5.6/en/create-view.html说:
ORDER BY
在视图定义中是允许的,但如果您使用具有自己的ORDER BY
.
因此,由视图运行以填充临时表的查询会忽略您视图的ORDER BY
,并且由于您使用了GROUP BY
它,它可能会从基础表中的任意行中获取值。
如何解决这个问题?停止运行不明确的GROUP BY
查询。在您的选择列表中引用的任何列都应该由 (a) 在GROUP BY
子句中列出,或 (b) 在诸如之类的分组函数中MAX()
。
我不知道你希望这个查询做什么,或者你为什么首先使用GROUP BY
。所以我不能提供任何更具体的建议。
回复您的评论:
感谢您的澄清。这是一种非常常见的 SQL 问题。我在 StackOverflow 上创建了每个组最大 n 个标签,现在它有近一千个问题。该标签存在于 dba.stackexchange.com 上,但到目前为止问题较少。
这是一个解决方案:
SELECT i.*
FROM inventoryrecords AS i
JOIN (SELECT TagEPC, MAX(StateDateUTC) AS StateDateUTC
FROM inventoryrecords
GROUP BY TagEPC ORDER BY NULL) AS maxi USING (TagEPC, StateDateUTC);
Run Code Online (Sandbox Code Playgroud)