我正在编写一个程序来处理一个名称取决于日期的 MySQL 表,格式为cdr_20131108
. 我的程序应该能够从任何给定日期的表中执行一些操作。
所有这些表都具有相同的结构,并包含一个time
字段。对于每一行,我需要检查前一小时有多少行满足某些条件。据我所知,我需要一个游标来查找当前行的时间,以及更多数据,然后准备并执行一个查询,从中可以找到我的结果。
在伪代码中:
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `myproc`()
BEGIN
DECLARE all necessary variables to save the data returned by the cursor
DECLARE c1 cursor for
select required fields
from cdr_20131103
where some criteria;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET _done = TRUE;
set @tablename := concat('rm_cdrs',date_format(curdate(),'%Y%m%d'));
set @entries := 0;
open c1;
c1_loop: loop
fetch c1 into my variables;
if `_done` then leave c1_loop; end if;
set @q := concat('... my query is prepared here: select count(*) into @variable (
select in which i look for rows that meet my criteria that
happened less tan an hour before the one in the cursor)');
PREPARE stmt FROM @q; EXECUTE stmt; DEALLOCATE PREPARE stmt;
if some criteria is met then do some stuff...
end loop c1_loop;
close c1;
END
因此,当我需要在不调整代码的情况下检查今天的表格时,我的问题就出现了,因为 MySQL 不允许我在这里使用变量:
DECLARE c1 cursor for
select required fields
from cdr_20131103
where some criteria;
我尝试在这里创建一个使用正确表名生成所需过程的过程,但 MySQL 不会让我从存储例程中删除或更改过程。
在这种情况下有什么解决方法吗?
在这种情况下我可以避免使用光标吗?
我应该按照此处的说明手动执行光标的任务吗?
此过程可能会使用 cron 定期调用。我是否应该只编写一些 Java/C/PHP 应用程序,在删除旧程序后创建并调用正确的程序?
非常感谢!
编辑:
@Sebas 声明可以通过使用单个插入选择语句来执行此操作。尽管他的回答中的视图技巧很有效,但我想尝试并从中学习。我将添加更多信息:
选择感兴趣的列并使用 where 子句过滤掉数据时,cdr_20131103
如下所示:
+---------+----------------+--------+
| user_ID | destination_ID | time |
+---------+----------------+--------+
| 2 | 56 | 110312 |
| 4 | 53 | 110513 |
| 2 | 56 | 110821 |
| 2 | 56 | 113212 | *
| 2 | 56 | 123001 |
+---------+----------------+--------+
我需要找出同一个 user_ID 在一个小时内访问同一个 destination_ID 至少 3 次的时间。因此,*
应该将带有的行与 now() 字段一起插入另一个表中。
我的线性思维告诉我应该逐一处理行,计算初始时间 ( time - interval 1 hour
,在该时间间隔中选择具有相同 User_ID 和 destination_ID 的行,计算它们并最终将它们插入另一个表中。
有没有更好的方法在 SQL 中做到这一点?
非常非常感谢你!