所以我有2张桌子communication,和movement。
communication
movement
communication具有列fromID,timestamp具有呼叫者的ID和进行呼叫的时间。然后,我有另一台movement已ID,timestamp,x,y,,有一个人,他们的位置的ID (x,y),而且它们在该位置的时间。
fromID
timestamp
ID
x
y
(x,y)
我想写一个看起来像这样的查询:
For every single row of communication(R) SELECT * FROM movement m WHERE m.ID = R.fromID && m.timestamp <= R.timestamp ORDER BY timestamp
基本上,这是在寻找movement timestamp给定值的最接近值communication timestamp。之后,最终,我想根据数据查找(x,y)呼叫的位置movement。
movement timestamp
communication timestamp
我该怎么做?我知道有一种基于集合的方法,但是我不想那样做。我调查了一下cursors,但是我感到在那方面的表现很糟糕……所以循环中是否有这样做的方法呢?我本质上是想遍历的每一行communication并获取结果…
cursors
我尝试过这样的事情:
DELMITER $$ CREATE PROCEDURE findClosestTimestamp() BEGIN DECLARE commRowCount DEFAULT 0; DECLARE i DEFAULT 0; DECLARE ctimestamp DEFAULT 0; SELECT COUNT(*) FROM communication INTO commRowCount; SET i = 0; WHILE i < commRowCount DO SELECT timestamp INTO ctimestamp FROM communication c SELECT * FROM movement m WHERE m.vID = c.fromID && m.timestamp <= R.timestamp END$$ DELIMITER ;
但是我知道那是完全错误的……是做这种游标的唯一方法吗?我只是在Internet上的任何地方都找不到这样的示例,而且我对SQL过程完全陌生。任何指导将不胜感激,谢谢!!
让我们看看我是否可以使用光标将您指向正确的方向:
delimiter $$ create procedure findClosestTimeStamp() begin -- Variables to hold values from the communications table declare cFromId int; declare cTimeStamp datetime; -- Variables related to cursor: -- 1. 'done' will be used to check if all the rows in the cursor -- have been read -- 2. 'curComm' will be the cursor: it will fetch each row -- 3. The 'continue' handler will update the 'done' variable declare done int default false; declare curComm cursor for select fromId, timestamp from communication; -- This is the query used by the cursor. declare continue handler for not found -- This handler will be executed if no row is found in the cursor (for example, if all rows have been read). set done = true; -- Open the cursor: This will put the cursor on the first row of its -- rowset. open curComm; -- Begin the loop (that 'loop_comm' is a label for the loop) loop_comm: loop -- When you fetch a row from the cursor, the data from the current -- row is read into the variables, and the cursor advances to the -- next row. If there's no next row, the 'continue handler for not found' -- will set the 'done' variable to 'TRUE' fetch curComm into cFromId, cTimeStamp; -- Exit the loop if you're done if done then leave loop_comm; end if; -- Execute your desired query. -- As an example, I'm putting a SELECT statement, but it may be -- anything. select * from movement as m where m.vID = cFromId and m.timeStamp <= cTimeStamp order by timestampdiff(SECOND, cTimeStamp, m.timeStamp) limit 1; end loop; -- Don't forget to close the cursor when you finish close curComm; end $$ delimiter ;