如果列总和小于 X 则更新行
Update rows if total column sum is less than X
我想弄清楚如何更新 table 中的行,如果它们的总大小小于 x
。
这是我的设置:
create table test_limit (
id int not null auto_increment primary key,
folder varchar(255),
status varchar(32) DEFAULT 'awaiting',
size bigint unsigned default 0,
request_id varchar(32)
)
ENGINE=InnoDB;
insert into test_limit
(folder, status, size)
values
('/tmp/AAA/bar', 'awaiting', 200 ),
('/tmp/AAA/bar', 'awaiting', 200 ),
('/tmp/AAA/bar', 'awaiting', 200 ),
('/tmp/BBB/bar', 'awaiting', 200 ),
('/tmp/BBB/bar', 'awaiting', 200 );
我有一个有 5 行的 table,每行都有一个大小我想要做的是更新一组行:
- 具有相同的
folder
值
- 状态不在
in_progress
或 created
- 总限制为 400
我想到了以下更新命令:
SET @request_id='bbb';
UPDATE test_limit t1
JOIN
( SELECT folder FROM test_limit WHERE status = 'awaiting' GROUP BY folder limit 1) t2
ON t1.folder = t2.folder
LEFT JOIN
( SELECT folder FROM test_limit WHERE status IN ('in_progress', 'created') GROUP BY folder limit 1) t3
ON t1.folder = t3.folder
JOIN
( SELECT id, @total := @total + size AS total FROM (test_limit, (select @total := 0) t) WHERE @total < 400 and status='awaiting') t4
ON t1.id=t4.id
SET t1.status = 'in_progress',
t1.request_id = @request_id
WHERE t1.status = 'awaiting' AND t3.folder is NULL;
但问题是第一次可以,其他时候就不行了:
mysql> select * from test_limit;
+----+--------------+-------------+------+------------+
| id | folder | status | size | request_id |
+----+--------------+-------------+------+------------+
| 1 | /tmp/AAA/bar | in_progress | 200 | bbb |
| 2 | /tmp/AAA/bar | in_progress | 200 | bbb |
| 3 | /tmp/AAA/bar | awaiting | 200 | NULL |
| 4 | /tmp/BBB/bar | awaiting | 200 | NULL |
| 5 | /tmp/BBB/bar | awaiting | 200 | NULL |
+----+--------------+-------------+------+------------+
5 rows in set (0.07 sec)
更新:
第一个 运行 以上结果是正确的。我想在第二个 运行 中实现什么(比如 request_id = 'aaa' ):
mysql> select * from test_limit;
+----+--------------+-------------+------+------------+
| id | folder | status | size | request_id |
+----+--------------+-------------+------+------------+
| 1 | /tmp/AAA/bar | in_progress | 200 | bbb |
| 2 | /tmp/AAA/bar | in_progress | 200 | bbb |
| 3 | /tmp/AAA/bar | awaiting | 200 | NULL |
| 4 | /tmp/BBB/bar | in_progress | 200 | aaa |
| 5 | /tmp/BBB/bar | in_progress | 200 | aaa |
+----+--------------+-------------+------+------------+
5 rows in set (0.07 sec)
而在第三个 运行 中,它不应更新任何内容,因为所有值都是 "in_progress"。
我怎样才能做到这一点?
这是一个使用存储过程的解决方案。尽管它比使用查询的解决方案更长,但您可能会发现此过程代码更易于理解和维护。当然执行方便:
CALL process_test_limit('AAA');
它是如何工作的?该过程从按 folder
排序的 test_limit
中获取行,并跟踪 id
直到 运行 总数达到 400 或 folder
发生变化。如果文件夹已经有 status
'in_process' 的记录,则该文件夹将被忽略。
DROP PROCEDURE IF EXISTS `process_test_limit`;
DELIMITER $$
CREATE PROCEDURE `process_test_limit` (IN p_request_id VARCHAR(32))
BEGIN
DECLARE v_sqlsafeupdates BOOLEAN; -- State of SQL_SAFE_UPDATES at execution start
DECLARE v_to_update CHAR(64); -- Name of temp table to store IDs of rows to be updated
DECLARE v_id INT;
DECLARE v_folder VARCHAR(255);
DECLARE v_size BIGINT UNSIGNED;
DECLARE v_running_total BIGINT UNSIGNED DEFAULT 0;
DECLARE v_prev_id INT DEFAULT NULL;
DECLARE v_prev_folder VARCHAR(255) DEFAULT NULL;
-- Cursor end handler flag (must be declared before cursors)
DECLARE v_cursor_end BOOLEAN DEFAULT FALSE;
-- Main cursor to iterate through the rows of test_limit
DECLARE c_test_limit CURSOR FOR
SELECT tl.id
, tl.folder
, tl.size
FROM test_limit tl
WHERE tl.status = 'awaiting'
AND NOT EXISTS (SELECT 1
FROM test_limit tl_check
WHERE tl_check.folder = tl.folder
AND tl_check.status = 'in_progress'
LIMIT 1
)
ORDER BY tl.folder -- Order is important: we process max one folder per call
, tl.size
;
-- Cursor end handler
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_cursor_end = TRUE;
-- Remember the current state of SQL_SAFE_UPDATES, then disable it
SET v_sqlsafeupdates = @@sql_safe_updates;
SET @@sql_safe_updates = FALSE;
-- Create temp table for tracking IDs of rows to update
SET v_to_update = CONCAT(
'process_test_limit_', CAST(UNIX_TIMESTAMP() AS CHAR), '_tmp'
);
SET @create_tmp_table_sql = CONCAT(
'CREATE TEMPORARY TABLE ', v_to_update,
' (id INT NOT NULL PRIMARY KEY) ENGINE=MEMORY'
);
PREPARE create_tmp_table_stmt FROM @create_tmp_table_sql;
EXECUTE create_tmp_table_stmt;
DEALLOCATE PREPARE create_tmp_table_stmt;
-- Prepare statement for saving IDs into "to update" tmp table
SET @save_id_sql = CONCAT('INSERT INTO ', v_to_update, ' (id) VALUES (?)');
PREPARE save_id_stmt FROM @save_id_sql;
-- Open the cursor to enable us to read the ordered result set one record at a time
OPEN c_test_limit;
-- Process the ordered test_limit records one-by-one
l_test_limit: LOOP
-- Get the next record (advance the cursor)
FETCH c_test_limit
INTO v_id, v_folder, v_size
;
-- Exit the loop if there are no more records to process
IF v_cursor_end THEN
LEAVE l_test_limit;
END IF;
-- First/same-as-last folder and running total not over 400? Save ID for update.
IF (v_prev_folder IS NULL OR v_folder = v_prev_folder) AND v_running_total + v_size <= 400 THEN
SET @id = CAST(v_id AS CHAR);
EXECUTE save_id_stmt USING @id;
-- Set variables for next iteration
SET v_prev_id = v_id;
SET v_prev_folder = v_folder;
SET v_running_total = v_running_total + v_size;
-- Different folder or running total over 400? Exit loop.
ELSE
LEAVE l_test_limit;
END IF;
END LOOP;
-- Deallocate statement for inserting rows into temp table
DEALLOCATE PREPARE save_id_stmt;
-- Update rows
SET @update_sql = CONCAT(
'UPDATE test_limit t INNER JOIN ', v_to_update, ' tmp',
' ON t.id = tmp.id',
' SET t.status = ?,',
' t.request_id = ?'
);
SET @status = 'in_progress';
SET @request_id = p_request_id;
PREPARE update_stmt FROM @update_sql;
EXECUTE update_stmt USING @status, @request_id;
DEALLOCATE PREPARE update_stmt;
-- Drop temp table
SET @drop_tmp_table_sql = CONCAT('DROP TEMPORARY TABLE ', v_to_update);
PREPARE drop_tmp_table_stmt FROM @drop_tmp_table_sql;
EXECUTE drop_tmp_table_stmt;
DEALLOCATE PREPARE drop_tmp_table_stmt;
-- Return SQL_SAFE_UPDATES to its original state at execution start
SET @@sql_safe_updates = v_sqlsafeupdates;
END$$
DELIMITER ;
结果确实满足您的要求:
-- Execution 1: 'AAA'
CALL process_test_limit('AAA');
SELECT * FROM test_limit;
-- id, folder, status, size, request_id
-- 1, /tmp/AAA/bar, in_progress, 200, AAA
-- 2, /tmp/AAA/bar, in_progress, 200, AAA
-- 3, /tmp/AAA/bar, awaiting, 200,
-- 4, /tmp/BBB/bar, awaiting, 200,
-- 5, /tmp/BBB/bar, awaiting, 200,
-- Execution 2: 'BBB'
CALL process_test_limit('BBB');
SELECT * FROM test_limit;
-- id, folder, status, size, request_id
-- 1, /tmp/AAA/bar, in_progress, 200, AAA
-- 2, /tmp/AAA/bar, in_progress, 200, AAA
-- 3, /tmp/AAA/bar, in_progress, 200,
-- 4, /tmp/BBB/bar, awaiting, 200, BBB
-- 5, /tmp/BBB/bar, awaiting, 200, BBB
-- Execution 3: 'CCC'
CALL process_test_limit('CCC');
SELECT * FROM test_limit;
-- id, folder, status, size, request_id
-- 1, /tmp/AAA/bar, in_progress, 200, AAA
-- 2, /tmp/AAA/bar, in_progress, 200, AAA
-- 3, /tmp/AAA/bar, in_progress, 200,
-- 4, /tmp/BBB/bar, in_progress, 200, BBB
-- 5, /tmp/BBB/bar, in_progress, 200, BBB
明白了,我花了一些时间来思考其中的逻辑。这里是sqlfiddlehttp://sqlfiddle.com/#!9/227dd0/1
UPDATE test_limit u
JOIN
(
SELECT
t1.*
,f.NonAwaitingFolderTotal
,(@runtot := @runtot + t1.size) as RunningTotal
FROM
(
SELECT
folder
,SUM(CASE WHEN status <> 'awaiting' THEN size ELSE 0 END) as NonAwaitingFolderTotal
FROM
test_limit t
GROUP BY
folder
HAVING
SUM(CASE WHEN status <> 'awaiting' THEN size ELSE 0 END) <= 400
ORDER BY
NonAwaitingFolderTotal, folder
LIMIT 1
) f
INNER JOIN test_limit t1
ON f.folder = t1.folder
CROSS JOIN (SELECT @runtot:=0) var
WHERE
t1.status = 'awaiting'
) t2
ON u.id = t2.id
AND (t2.NonAwaitingFolderTotal + t2.RunningTotal) <= 400
SET
u.status = 'in_progress'
,u.request_id = @request_id
;
逻辑是这样的
- 找到要使用的文件夹并找到该文件夹中当前的非等待总大小。然后 select 最小非等待大小的文件夹(in_progress,已创建),如果按文件夹名称绑定,则限制为 1。
- 获取该文件夹中所有等待记录的 运行 总数,用于确定在达到允许的最大值之前可以更新哪些行。
- 通过连接 运行 总计查询的结果进行更新,其中 NonAwaiting 记录的总大小 + 运行 该记录的总数小于最大值 400。
只是因为我想把它放在某个地方,主要问题是 运行 总的来说,你使用的地方没有按正确的级别分组。这里有几个 运行 总计和行号函数我一直在思考它。
SELECT
*
,(@foldercount := IF(@prevfolder=folder,@foldercount,@foldercount+1)) as FolderNum
,(@rownum := @rownum + 1) as RowNum
,(@grouprownum := IF(@prevfolder=folder,@grouprownum+1,1)) as GroupRowNum
,(@total := IF(@prevfolder=folder,@total + t.size,t.size)) as GroupRunningTotal
,(@GroupAwaitRunningTotal := IF(
@prevfolder=folder
,IF(t.status = 'awaiting',@GroupAwaitRunningTotal + t.size,@GroupAwaitRunningTotal)
,IF(t.status = 'awaiting',t.size,0)
)
) as GroupAwaitRunningTotal
,(@GroupNonAwaitRunningTotal := IF(
@prevfolder=folder
,IF(t.status != 'awaiting',@GroupNonAwaitRunningTotal + t.size,@GroupNonAwaitRunningTotal)
,IF(t.status != 'awaiting',t.size,0)
)
) as GroupNonAwaitRunningTotal
,(@runtot := @runtot + t.size) as RunningTotal
,@prevfolder:=folder
FROM
test_limit t
CROSS JOIN
(SELECT @prevfolder:=NULL, @GroupAwaitRunningTotal := 0
,@GroupNonAwaitRunningTotal := 0
,@total:=0, @rownum:=0, @grouprownum:=0, @runtot:=0, @foldercount:=0) var
我想弄清楚如何更新 table 中的行,如果它们的总大小小于 x
。
这是我的设置:
create table test_limit (
id int not null auto_increment primary key,
folder varchar(255),
status varchar(32) DEFAULT 'awaiting',
size bigint unsigned default 0,
request_id varchar(32)
)
ENGINE=InnoDB;
insert into test_limit
(folder, status, size)
values
('/tmp/AAA/bar', 'awaiting', 200 ),
('/tmp/AAA/bar', 'awaiting', 200 ),
('/tmp/AAA/bar', 'awaiting', 200 ),
('/tmp/BBB/bar', 'awaiting', 200 ),
('/tmp/BBB/bar', 'awaiting', 200 );
我有一个有 5 行的 table,每行都有一个大小我想要做的是更新一组行:
- 具有相同的
folder
值 - 状态不在
in_progress
或created
- 总限制为 400
我想到了以下更新命令:
SET @request_id='bbb';
UPDATE test_limit t1
JOIN
( SELECT folder FROM test_limit WHERE status = 'awaiting' GROUP BY folder limit 1) t2
ON t1.folder = t2.folder
LEFT JOIN
( SELECT folder FROM test_limit WHERE status IN ('in_progress', 'created') GROUP BY folder limit 1) t3
ON t1.folder = t3.folder
JOIN
( SELECT id, @total := @total + size AS total FROM (test_limit, (select @total := 0) t) WHERE @total < 400 and status='awaiting') t4
ON t1.id=t4.id
SET t1.status = 'in_progress',
t1.request_id = @request_id
WHERE t1.status = 'awaiting' AND t3.folder is NULL;
但问题是第一次可以,其他时候就不行了:
mysql> select * from test_limit;
+----+--------------+-------------+------+------------+
| id | folder | status | size | request_id |
+----+--------------+-------------+------+------------+
| 1 | /tmp/AAA/bar | in_progress | 200 | bbb |
| 2 | /tmp/AAA/bar | in_progress | 200 | bbb |
| 3 | /tmp/AAA/bar | awaiting | 200 | NULL |
| 4 | /tmp/BBB/bar | awaiting | 200 | NULL |
| 5 | /tmp/BBB/bar | awaiting | 200 | NULL |
+----+--------------+-------------+------+------------+
5 rows in set (0.07 sec)
更新:
第一个 运行 以上结果是正确的。我想在第二个 运行 中实现什么(比如 request_id = 'aaa' ):
mysql> select * from test_limit;
+----+--------------+-------------+------+------------+
| id | folder | status | size | request_id |
+----+--------------+-------------+------+------------+
| 1 | /tmp/AAA/bar | in_progress | 200 | bbb |
| 2 | /tmp/AAA/bar | in_progress | 200 | bbb |
| 3 | /tmp/AAA/bar | awaiting | 200 | NULL |
| 4 | /tmp/BBB/bar | in_progress | 200 | aaa |
| 5 | /tmp/BBB/bar | in_progress | 200 | aaa |
+----+--------------+-------------+------+------------+
5 rows in set (0.07 sec)
而在第三个 运行 中,它不应更新任何内容,因为所有值都是 "in_progress"。
我怎样才能做到这一点?
这是一个使用存储过程的解决方案。尽管它比使用查询的解决方案更长,但您可能会发现此过程代码更易于理解和维护。当然执行方便:
CALL process_test_limit('AAA');
它是如何工作的?该过程从按 folder
排序的 test_limit
中获取行,并跟踪 id
直到 运行 总数达到 400 或 folder
发生变化。如果文件夹已经有 status
'in_process' 的记录,则该文件夹将被忽略。
DROP PROCEDURE IF EXISTS `process_test_limit`;
DELIMITER $$
CREATE PROCEDURE `process_test_limit` (IN p_request_id VARCHAR(32))
BEGIN
DECLARE v_sqlsafeupdates BOOLEAN; -- State of SQL_SAFE_UPDATES at execution start
DECLARE v_to_update CHAR(64); -- Name of temp table to store IDs of rows to be updated
DECLARE v_id INT;
DECLARE v_folder VARCHAR(255);
DECLARE v_size BIGINT UNSIGNED;
DECLARE v_running_total BIGINT UNSIGNED DEFAULT 0;
DECLARE v_prev_id INT DEFAULT NULL;
DECLARE v_prev_folder VARCHAR(255) DEFAULT NULL;
-- Cursor end handler flag (must be declared before cursors)
DECLARE v_cursor_end BOOLEAN DEFAULT FALSE;
-- Main cursor to iterate through the rows of test_limit
DECLARE c_test_limit CURSOR FOR
SELECT tl.id
, tl.folder
, tl.size
FROM test_limit tl
WHERE tl.status = 'awaiting'
AND NOT EXISTS (SELECT 1
FROM test_limit tl_check
WHERE tl_check.folder = tl.folder
AND tl_check.status = 'in_progress'
LIMIT 1
)
ORDER BY tl.folder -- Order is important: we process max one folder per call
, tl.size
;
-- Cursor end handler
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_cursor_end = TRUE;
-- Remember the current state of SQL_SAFE_UPDATES, then disable it
SET v_sqlsafeupdates = @@sql_safe_updates;
SET @@sql_safe_updates = FALSE;
-- Create temp table for tracking IDs of rows to update
SET v_to_update = CONCAT(
'process_test_limit_', CAST(UNIX_TIMESTAMP() AS CHAR), '_tmp'
);
SET @create_tmp_table_sql = CONCAT(
'CREATE TEMPORARY TABLE ', v_to_update,
' (id INT NOT NULL PRIMARY KEY) ENGINE=MEMORY'
);
PREPARE create_tmp_table_stmt FROM @create_tmp_table_sql;
EXECUTE create_tmp_table_stmt;
DEALLOCATE PREPARE create_tmp_table_stmt;
-- Prepare statement for saving IDs into "to update" tmp table
SET @save_id_sql = CONCAT('INSERT INTO ', v_to_update, ' (id) VALUES (?)');
PREPARE save_id_stmt FROM @save_id_sql;
-- Open the cursor to enable us to read the ordered result set one record at a time
OPEN c_test_limit;
-- Process the ordered test_limit records one-by-one
l_test_limit: LOOP
-- Get the next record (advance the cursor)
FETCH c_test_limit
INTO v_id, v_folder, v_size
;
-- Exit the loop if there are no more records to process
IF v_cursor_end THEN
LEAVE l_test_limit;
END IF;
-- First/same-as-last folder and running total not over 400? Save ID for update.
IF (v_prev_folder IS NULL OR v_folder = v_prev_folder) AND v_running_total + v_size <= 400 THEN
SET @id = CAST(v_id AS CHAR);
EXECUTE save_id_stmt USING @id;
-- Set variables for next iteration
SET v_prev_id = v_id;
SET v_prev_folder = v_folder;
SET v_running_total = v_running_total + v_size;
-- Different folder or running total over 400? Exit loop.
ELSE
LEAVE l_test_limit;
END IF;
END LOOP;
-- Deallocate statement for inserting rows into temp table
DEALLOCATE PREPARE save_id_stmt;
-- Update rows
SET @update_sql = CONCAT(
'UPDATE test_limit t INNER JOIN ', v_to_update, ' tmp',
' ON t.id = tmp.id',
' SET t.status = ?,',
' t.request_id = ?'
);
SET @status = 'in_progress';
SET @request_id = p_request_id;
PREPARE update_stmt FROM @update_sql;
EXECUTE update_stmt USING @status, @request_id;
DEALLOCATE PREPARE update_stmt;
-- Drop temp table
SET @drop_tmp_table_sql = CONCAT('DROP TEMPORARY TABLE ', v_to_update);
PREPARE drop_tmp_table_stmt FROM @drop_tmp_table_sql;
EXECUTE drop_tmp_table_stmt;
DEALLOCATE PREPARE drop_tmp_table_stmt;
-- Return SQL_SAFE_UPDATES to its original state at execution start
SET @@sql_safe_updates = v_sqlsafeupdates;
END$$
DELIMITER ;
结果确实满足您的要求:
-- Execution 1: 'AAA'
CALL process_test_limit('AAA');
SELECT * FROM test_limit;
-- id, folder, status, size, request_id
-- 1, /tmp/AAA/bar, in_progress, 200, AAA
-- 2, /tmp/AAA/bar, in_progress, 200, AAA
-- 3, /tmp/AAA/bar, awaiting, 200,
-- 4, /tmp/BBB/bar, awaiting, 200,
-- 5, /tmp/BBB/bar, awaiting, 200,
-- Execution 2: 'BBB'
CALL process_test_limit('BBB');
SELECT * FROM test_limit;
-- id, folder, status, size, request_id
-- 1, /tmp/AAA/bar, in_progress, 200, AAA
-- 2, /tmp/AAA/bar, in_progress, 200, AAA
-- 3, /tmp/AAA/bar, in_progress, 200,
-- 4, /tmp/BBB/bar, awaiting, 200, BBB
-- 5, /tmp/BBB/bar, awaiting, 200, BBB
-- Execution 3: 'CCC'
CALL process_test_limit('CCC');
SELECT * FROM test_limit;
-- id, folder, status, size, request_id
-- 1, /tmp/AAA/bar, in_progress, 200, AAA
-- 2, /tmp/AAA/bar, in_progress, 200, AAA
-- 3, /tmp/AAA/bar, in_progress, 200,
-- 4, /tmp/BBB/bar, in_progress, 200, BBB
-- 5, /tmp/BBB/bar, in_progress, 200, BBB
明白了,我花了一些时间来思考其中的逻辑。这里是sqlfiddlehttp://sqlfiddle.com/#!9/227dd0/1
UPDATE test_limit u
JOIN
(
SELECT
t1.*
,f.NonAwaitingFolderTotal
,(@runtot := @runtot + t1.size) as RunningTotal
FROM
(
SELECT
folder
,SUM(CASE WHEN status <> 'awaiting' THEN size ELSE 0 END) as NonAwaitingFolderTotal
FROM
test_limit t
GROUP BY
folder
HAVING
SUM(CASE WHEN status <> 'awaiting' THEN size ELSE 0 END) <= 400
ORDER BY
NonAwaitingFolderTotal, folder
LIMIT 1
) f
INNER JOIN test_limit t1
ON f.folder = t1.folder
CROSS JOIN (SELECT @runtot:=0) var
WHERE
t1.status = 'awaiting'
) t2
ON u.id = t2.id
AND (t2.NonAwaitingFolderTotal + t2.RunningTotal) <= 400
SET
u.status = 'in_progress'
,u.request_id = @request_id
;
逻辑是这样的
- 找到要使用的文件夹并找到该文件夹中当前的非等待总大小。然后 select 最小非等待大小的文件夹(in_progress,已创建),如果按文件夹名称绑定,则限制为 1。
- 获取该文件夹中所有等待记录的 运行 总数,用于确定在达到允许的最大值之前可以更新哪些行。
- 通过连接 运行 总计查询的结果进行更新,其中 NonAwaiting 记录的总大小 + 运行 该记录的总数小于最大值 400。
只是因为我想把它放在某个地方,主要问题是 运行 总的来说,你使用的地方没有按正确的级别分组。这里有几个 运行 总计和行号函数我一直在思考它。
SELECT
*
,(@foldercount := IF(@prevfolder=folder,@foldercount,@foldercount+1)) as FolderNum
,(@rownum := @rownum + 1) as RowNum
,(@grouprownum := IF(@prevfolder=folder,@grouprownum+1,1)) as GroupRowNum
,(@total := IF(@prevfolder=folder,@total + t.size,t.size)) as GroupRunningTotal
,(@GroupAwaitRunningTotal := IF(
@prevfolder=folder
,IF(t.status = 'awaiting',@GroupAwaitRunningTotal + t.size,@GroupAwaitRunningTotal)
,IF(t.status = 'awaiting',t.size,0)
)
) as GroupAwaitRunningTotal
,(@GroupNonAwaitRunningTotal := IF(
@prevfolder=folder
,IF(t.status != 'awaiting',@GroupNonAwaitRunningTotal + t.size,@GroupNonAwaitRunningTotal)
,IF(t.status != 'awaiting',t.size,0)
)
) as GroupNonAwaitRunningTotal
,(@runtot := @runtot + t.size) as RunningTotal
,@prevfolder:=folder
FROM
test_limit t
CROSS JOIN
(SELECT @prevfolder:=NULL, @GroupAwaitRunningTotal := 0
,@GroupNonAwaitRunningTotal := 0
,@total:=0, @rownum:=0, @grouprownum:=0, @runtot:=0, @foldercount:=0) var