Get and add next row column value to first row column - mysql

I have a database table which as below
I want to add each SoldD column to next row ValT column.
for example, query result for above given table should be like as
Above snapshot is for expected Results
so for, I have tried many things but failed to get expected results
Failed try 1:
SELECT *,(IFNULL((SELECT VaIT from saleorder s WHERE s.id > ss.id limit 1),0)+ss.SoldD) FROM `saleorder` ss
Failed try 2:
update saleorder SET SoldD=(IFNULL((SELECT VaIT from (SELECT * from saleorder WHERE id > id+1 limit 1) s),0)+SoldD)
Any help is highly appreciated, Thanks in advance!

MySql version:
CREATE DEFINER=`root`#`localhost` PROCEDURE `new_procedure`()
BEGIN
DECLARE id2 INT DEFAULT 0;
declare VALT2 INT DEFAULT 0;
declare soldD2 INT DEFAULT 0;
declare beforSo2 INT DEFAULT 0;
DECLARE cur1 CURSOR FOR SELECT Id, ValT, SoldD FROM saleorder ORDER BY id;
OPEN cur1;
FETCH cur1 INTO id2, VALT2, soldD2;
SET valT2 = soldD2;
x: LOOP
IF(valT2 IS NULL) THEN
SET valT2 = 0;
END IF;
IF(beforSo2 IS NULL) THEN
SET beforSo2 = 0;
END IF;
UPDATE saleorder
SET SoldD = beforSo2 + valT2
WHERE ID = id2;
SET beforSo2 = beforSo2 + valT2;
FETCH cur1 INTO id2, VALT2, soldD2;
END LOOP;
CLOSE cur1;
END
Then call procedure this way:
CALL new_procedure;
SqlServer version:
DECLARE db_cursor CURSOR FOR SELECT ID, ValT, SoldD FROM Table_2 ORDER BY ID;
DECLARE #ID INT;
DECLARE #valT INT;
DECLARE #soldD INT;
DECLARE #beforSoldD INT = 0;
OPEN db_cursor;
FETCH NEXT FROM db_cursor INTO #ID, #valT, #soldD;
SET #valT = #soldD;
WHILE ##FETCH_STATUS = 0
BEGIN
IF(#valT IS NULL)
SET #valT = 0;
IF(#beforSoldD IS NULL)
SET #beforSoldD = 0;
UPDATE Table_2
SET SoldD = #beforSoldD + #valT
WHERE ID = #ID;
SET #beforSoldD = #beforSoldD + #valT;
FETCH NEXT FROM db_cursor INTO #ID, #valT, #soldD;
END;
CLOSE db_cursor;
DEALLOCATE db_cursor;
Base data:
Result:

Related

MySqlException: Subquery returns more than 1 row, for a stored procedure with a cursor

Hello I have the following stored procedure for MySQL but when it is executed in my ASP.NET Core application I get a Subquery returns more than 1 row error. What am I doing wrong here? The equivalent SQL Server version used to work without problems...
-- System Calculates Candidate’s Matching Score based on a Manager’s Answer Weights
CREATE PROCEDURE spSysCalcCandScore
(
IN Candidate_ID INT,
IN Manager_ID INT
)
Begin
DECLARE ansID INT;
DECLARE tempSum INT;
DECLARE Sum INT;
DECLARE Done INT DEFAULT FALSE;
DECLARE MyCursor CURSOR FOR
SELECT Answer_ID FROM Completed_Questionnaire
WHERE Candidate_ID = Candidate_ID;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET Done = TRUE;
START TRANSACTION;
OPEN MyCursor;
myloop: LOOP
FETCH MyCursor INTO ansID;
IF Done THEN
LEAVE myloop;
END IF;
SET tempSum = (SELECT Weight_Value FROM Weight WHERE (Answer_ID = ansID AND Manager_ID = Manager_ID));
SET Sum = Sum + tempSum;
END LOOP;
CLOSE MyCursor;
IF (Sum IS NULL) THEN
SET Sum = 0;
END IF;
UPDATE `Interest`
SET Matching_Score = Sum
WHERE (Candidate_ID = Candidate_ID AND Manager_ID = Manager_ID);
COMMIT;
End//

MySQL Inner cursor executes only one time

DELIMITER $$
CREATE PROCEDURE `remove_schedule_duplicate` ()
BEGIN
BLOCK1 : BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE schedule_id CHAR(36);
DECLARE gamePk INTEGER;
DECLARE keep_entry TINYINT(1);
DECLARE scheduleDuplicate CURSOR FOR SELECT game_pk FROM schedule where is_active = 1 group by game_pk,home_team_id,away_team_id,venue_id having count(game_pk) > 1 limit 2;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
OPEN scheduleDuplicate;
get_schedule_duplicate: LOOP
FETCH scheduleDuplicate INTO gamePk;
IF finished = 1 THEN
LEAVE get_schedule_duplicate;
END IF;
**BLOCK2 : BEGIN
DECLARE block_finished INTEGER DEFAULT 0;
DECLARE blockDuplicate CURSOR FOR SELECT id FROM schedule where game_pk = gamePk and is_active = 1;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET block_finished = 1;
OPEN blockDuplicate;
block_schedule_duplicate: LOOP
FETCH blockDuplicate INTO schedule_id;
IF block_finished = 1 THEN
LEAVE block_schedule_duplicate;
END IF;
IF keep_entry = 0 THEN
UPDATE schedule set is_active = 0 where id = schedule_id;
END IF;
END LOOP block_schedule_duplicate;
CLOSE blockDuplicate;
END BLOCK2;**
END LOOP get_schedule_duplicate;
CLOSE scheduleDuplicate;
END BLOCK1;
END
$$
The problem is Innerloop first time execute well after that block_finished always be 1 so. always it quits the inner block.
How to resolve this issue. What i do ? Some one help me to resolve the issue.
I have Changed My Stored procedure like this:
DELIMITER $$
CREATE PROCEDURE `remove_schedule_duplicate`()
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE schedule_id,temp CHAR(36) DEFAULT NULL;
DECLARE gamePk INTEGER;
DECLARE keep_entry TINYINT(1);
DECLARE scheduleDuplicate CURSOR FOR SELECT game_pk,id FROM schedule where game_pk in (SELECT game_pk FROM schedule where is_active = 1 group by game_pk,home_team_id,away_team_id,venue_id having count(game_pk) > 1) and is_active = 1 order by game_pk;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
OPEN scheduleDuplicate;
get_schedule_duplicate: LOOP
FETCH scheduleDuplicate INTO gamePk,schedule_id;
IF finished = 1 THEN
LEAVE get_schedule_duplicate;
END IF;
IF ((temp IS NULL) AND (gamePk IS NOT NULL)) OR ((temp IS NOT NULL) AND (temp <> gamePk)) THEN
SET temp = gamePk;
SET keep_entry = 1;
#ELSE IF temp IS NOT NULL AND temp = gamePk THEN
ELSE
SET keep_entry = 0;
END IF;
IF keep_entry = 0 THEN
UPDATE schedule set is_active = 0 where id = schedule_id;
END IF;
END LOOP get_schedule_duplicate;
CLOSE scheduleDuplicate;
END$$
DELIMITER ;

Find the values in table with cursor

i have a table with one column id and this column have (1,2,3,5,8,12,15,20)
i have find values that not in table WHIT CURSOR
this is a practice for Cursor
my query had error
please help me
declare cur cursor for select id from T7
open cur
declare #id int
declare #show1 int
declare #show2 int
declare #temp table (number int)
fetch next from cur into #id
while ##FETCH_STATUS = 0
begin
set #show1 = #id
fetch next from cur into #id
set #show2 = #id
if #show2 - #show1 = 1
begin
print 'true'
end
while #show2 - #show1 !=1
begin
set #show2 = #show2 - 1
insert into #temp select #show2
end
end
select * from #temp order by number asc
close cur
Thanks for taking
I do not have the numbers in this table
example values (4,6,7,9,10,11,13,14,16,17,18,19) in table temp

populating table in stored procedure, mysql

Can anyone shed light on why this will not loop through the function and populate the temp table? Ive tried a number of things and at best can only get the first value to populate. I'm trying to take a value and a ":" separated string (queried in this procedure) to populate a table so I can reference it in a larger query. The function SPLIT_STR works great on its own but I cant seem to increment value "a" so that it separates ALL values per field per value.
BEGIN
DECLARE platform_val VARCHAR(255);
DECLARE productName_val VARCHAR(255);
DECLARE no_more_rows BOOLEAN;
DECLARE num_rows INT DEFAULT 0;
DECLARE loop_cntr INT DEFAULT 0;
DECLARE str VARCHAR(255);
DECLARE a INT DEFAULT 1;
DECLARE cur1 CURSOR FOR SELECT
ProductName,
ProductPlatforms
FROM Feed
limit 10;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_more_rows = TRUE;
OPEN cur1;
select FOUND_ROWS() into num_rows;
the_loop: LOOP
FETCH cur1
INTO productName_val,
platform_val;
SET str = platform_val;
WHILE a< num_rows DO
SET str=SPLIT_STR(str,":",a);
insert into temp values (productName_val, str);
SET a=a+1;
END WHILE;
END LOOP the_loop;
END
This is the idea I came up with
CREATE PROCEDURE `col2lines`()
BEGIN
declare v_platform,v_productName,v_platformAll varchar(255) default null;
declare v_finished int default 0;
declare curs cursor for select ProductName,ProductPlatforms from Feed limit 10;
declare continue handler for not found set v_finished = 1;
drop temporary table if exists temp_table;
create temporary table temp_table (
productName varchar(255),
platform varchar(255)
);
open curs;
parent: LOOP
fetch curs into v_productName, v_platformAll;
if (v_finished = 1) then LEAVE parent; end if;
child: LOOP
set v_platform = substring_index(v_platformAll, '::', 1);
set #strlen = char_length(v_platform);
if (#strlen > 0) then
insert into temp_table values (v_productName, v_platform);
set v_platformAll = substr(v_platformAll, #strlen + 3);
iterate child;
end if;
LEAVE child;
END LOOP child;
iterate parent;
END LOOP parent;
close curs;
select * from temp_table;
END

Issue in adding two outputs from MySQL function inside another function

CREATE DEFINER=`root`#`localhost` FUNCTION `F_GetProjectCostPerEmployeeInProject`(id VARCHAR(20)) RETURNS DECIMAL(30,2)
BEGIN
DECLARE e_id VARCHAR(20);
DECLARE finished INT ;
DECLARE temp DECIMAL(30,2);
DECLARE temp2 DECIMAL(30,2);
DECLARE TotalCostOfEmployees DECIMAL(30,2);
DECLARE cur CURSOR FOR SELECT DISTINCT e_id FROM project_employee WHERE project_id=id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
emploop : LOOP
FETCH cur INTO e_id;
IF finished =1 ;
LEAVE emploop;
END IF ;
SET TotalCostOfEmployees = TotalCostOfEmployees + ( F_TotalManDaysPerEmployee(e_id,id)*(F_GetEmployeeGradeSal(e_id));
END LOOP emploop;
RETURN TotalCostOfEmployees;
END$$
The problem is its giving error at line :
SET TotalCostOfEmployees = TotalCostOfEmployees + ( F_TotalManDaysPerEmployee(e_id,id)*(F_GetEmployeeGradeSal(e_id));
This is the error :
Error Code : 1064 You have an error in
your SQL syntax; check the manual that
corresponds to your MySQL server
version for the right syntax to use
near '; leave emploop; end if ;
set TotalCostOfEmployees = TotalCostOfEmploy' at line 12
Use the SELECT ... INTO clause
SELECT TotalCostOfEmployees + ( F_TotalManDaysPerEmployee(e_id,id)*(F_GetEmployeeGradeSal(e_id))
INTO TotalCostOfEmployees;
Why are you using a cursor for this at all?
SELECT SUM(F_TotalManDaysPerEmployee(e_id, id) * F_GetEmployeeGradeSal(e_id)) AS TotalCostOfEmployees
FROM (
SELECT DISTINCT e_id
FROM project_employee
WHERE project_id = id
) q
I solved it via this way:
enter code BEGIN DECLARE e_id VARCHAR(20);
DECLARE finished INT ;
DECLARE salary DECIMAL(30,2);
DECLARE TotalCostOfEmployees DECIMAL(30,2) ;
DECLARE cur CURSOR FOR SELECT DISTINCT Emp_code FROM project_employee WHERE project_id=p_id;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
SET finished = 0;
OPEN cur;
SET TotalCostOfEmployees =0.0;
emploop : LOOP
FETCH cur INTO e_id;
IF finished = 1 THEN
LEAVE emploop;
END IF ;
SELECT COALESCE( (F_TotalManDaysPerEmployee(e_id,p_id)* F_GetEmployeeGradeSal(e_id))/22,0.0)
INTO salary;
SET TotalCostOfEmployees = TotalCostOfEmployees + salary;
/*SELECT (TotalCostOfEmployees + ifnull(salary,0.0)) into TotalCostOfEmployees; */
END LOOP emploop;
CLOSE cur;
RETURN TotalCostOfEmployees;
END$$