Impoving performance of query by using greater than on a primary key
Assuming that valueStr has a Unique constraint on the second table, so the following query will always yield at most one row:

SELECT last_sno 
FROM tableB 
WHERE valueStr ='ABC'


You can use it as a subquery (or a derived table) to run an INSERT ... ON DUPLICATE KEY UPDATE:

INSERT INTO tableB 
  (valueStr, total_mins, last_sno)
SELECT 
  'ABC', SUM(a.mins), MAX(a.sno)
FROM tableA AS a
WHERE a.sno &gt; COALESCE(
          ( SELECT last_sno 
            FROM tableB 
            WHERE valueStr ='ABC'
          ), 0) 
  AND a.description LIKE 'ABC%'
ON DUPLICATE KEY UPDATE
  total_mins = total_mins + VALUES(total_mins),
  last_sno = VALUES(last_sno) ;




Regarding efficiency, the condition you have

WHERE a.sno &gt; @last_sno
  AND a.description LIKE 'ABC%'


is basically two range conditions, one on sno and one on description (think of description LIKE 'ABC%' the same as description &gt;= 'ABC' AND description &lt; 'ABD') which is rather hard to optimize. The optimizer will have to choose one index to use, it can't use both indexes for this query.

If you could split the description column or add one more with the first (three or more) characters of description that uniquely identify the value_str, making tableA something like this:

tableA

sno   | Project |name     | description      | value_str | mins |
1     | prjA    |nameA    |ABC -10% task done| ABC       | 30   |
...
3000  | prjA    |nameB    |ABC -70% task done| ABC       | 70   |


then you could write the conditions as:

WHERE a.sno &gt; @last_sno
  AND a.value_str = 'ABC'


and a composite index on (value_str, sno) would make this and similar queries much more efficient than what you have now.