2015-06-11 2 views
0

Итак, у меня есть 2 стола, communication и movement.SQL - Зацикливание через строку таблицы в mysql?

communication имеет столбцы fromID, timestamp, который имеет идентификатор вызывающего абонента и время вызова. Затем у меня есть другая таблица movement, которая имеет ID, timestamp, 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.

Как мне это сделать? Я знаю, что существует основанный на наборе подход, но я не хочу так поступать. Я заглянул в cursors, но у меня такое ощущение, что производительность ужасна в этом ... так что все равно нужно сделать это с помощью цикла? Я по существу хочу Перебери каждую строку communication, и получить результат ...

Я пытался что-то вроде этого:

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 ; 

Но я знаю, Thats совершенно неправильно ... Это единственный способ делать это курсоры ??? Я просто не могу найти пример этого в любом месте в Интернете, и я совершенно не знаком с процедурами в SQL. Любое руководство будет принята с благодарностью, спасибо!

+1

"Я знаю, что есть набор на основе но я не хочу так поступать ». Почему нет? Что такое РСУБД? –

+0

Ну, у меня уже есть версия на основе набора ... но я не должен делать это в формате, основанном на наборе, к сожалению. – ocean800

+0

@ ocean800 Вам нужно только один ряд («ближайший») от движения? – Barranka

ответ

2

Давайте посмотрим, если я могу указать вам в правильном направлении, используя курсоры:

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 ; 

рекомендации:

+0

Большое вам спасибо! Я даже не могу сказать, насколько это помогает :) – ocean800

+1

@ ocean800 рад помочь. Я отредактировал свой ответ, чтобы включить ссылки на соответствующие разделы справочного руководства. Я предлагаю вам прочитать их. ура – Barranka