我有一张桌子locations
:
user | timestamp | state | other_data
-------------------------------------
1 100 1 some_data
1 200 1 some_data
1 300 0 some_data
1 400 0 some_data
2 100 0 some_data
2 200 0 some_data
这适用于位置跟踪应用。一个位置有两个state
s(1个用于"用户在范围内" 0用于"用户超出范围")。
现在我想检索用户上次位置状态的更改。
user
= 1
user | timestamp | state | other_data
-------------------------------------
1 300 0 some_data
因为这是第一个与"当前"具有相同state
值的位置更新。 (timestamp
400)记录。
更高级别的描述:我希望向用户显示类似"您已经进入/超出范围,因为[时间戳]"
解决方案越快,当然越好
答案 0 :(得分:2)
我会使用排名来排序行,然后选择排名第一行的min
时间戳。
select user,min(timestamp) as timestamp,min(state) as state
from
(select l.*,@rn:=case when @user=user and @state=state then @rn
when @user<>user then 1
else @rn+1 end as rnk
,@user:=user,@state:=state
from locations l
cross join (select @rn:=0,@user:='',@state:='') r
order by user,timestamp desc
) t
where rnk=1
group by user
答案 1 :(得分:1)
您可以使用相关子查询执行此操作:
select l.*
from locations l
where l.timestamp = (select max(l2.timestamp)
from locations l2
where l2.user = l.user
);
为了使其运作良好,您需要locations(user, timestamp)
上的索引。
这可能比join
和group by
方法更快。特别是,相关子查询可以使用索引,但整个表中的group by
通常不会(在MySQL中)。
答案 2 :(得分:0)
据我所知,实现这一目标的唯一方法是销售加盟。有点像的东西;
function replacebackenddatabase() {
var ui = SpreadsheetApp.getUi();
var result = ui.prompt(
'Ask a question...',
ui.ButtonSet.OK_CANCEL);
// Get the response...
var button = result.getSelectedButton();
var text = result.getResponseText();
if (button == ui.Button.OK) {
//If they clicked OK do something with 'text' variable
} else if (button == ui.Button.CANCEL) {
// If they clicked Cancel.
} else if (button == ui.Button.CLOSE) {
// If they closed the prompt
}
}
语法适用于MsSQL,它应该转移到MySQL。可能必须指定列名而不是表。*