MYSQL INSERT IF SUMs > CONSTANT - mysql

I'm trying to insert a record if a sum of 3 user columns from 2 tables exceeds a constant.
I've searched all over, found you can't put user variables in IFs, WHERE's etc. Found you can't put SUMs in IFs, WHERE's etc. I'm at a total loss. Here's an example of my earlier bad code before unsuccessfully trying to use SUMs in WHEREs, if it helps:
SELECT SUM(num1) INTO #mun1 FROM table1 WHERE user = '0';
SELECT SUM(num2) INTO #mun2 FROM table1 WHERE user = '0';
SELECT SUM(num3) INTO #mun3 FROM table2 WHERE column1 = 'd' AND user = '0';
SET #mun4 = #mun1 - #mun2 - #mun3;
INSERT INTO table2 (user, column1, column2) VALUES ('0', 'd', '100') WHERE #mun4 >= 100;

Try this:
INSERT INTO table2 (user, column1, column2)
select '0', 'd', '100'
from dual
where (SELECT SUM(num1 + num2) FROM table1 WHERE user = '0') +
(SELECT SUM(num3) FROM table2 WHERE column1 = 'd' AND user = '0') > 100;
This is a case of the general solution for a "insert if condition" problem:
insert into ... select ... where condition
The select will only return rows if the condition is true, and importantly, will return no rows if false - meaning the insert only happens if the condition is true, otherwise nothing happens.

This is same as #Bohemian's answer, but you got to add a LIMIT clause to stop inserting multiple records, since select clause may return multiple records
INSERT INTO table2 (user, column1, column2)
SELECT '0', 'd', '100'
FROM dual
WHERE
(SELECT SUM(num1 - num2) FROM table1 WHERE user = '0')
(SELECT SUM(num3) FROM table2 WHERE column1 = 'd' AND user = '0') >
100
LIMIT 1

Related

Insert in the IF statement Query in mysql

Is there a way to run an insert query in the IF statement, As I know the syntax for if statement is
IF(conditon, execute if condition is True, execute if condition is False)
My question is whether if it is possible run an insert statement based on the conditions, like
IF((select count(*) from table where id = x) = 0, insert1, insert2)
insert1 will be a direct insert like
insert into table (col1,col2..) values (val1, val2..)
insert2 will fetch the previous value with the id whose count is not 0 and then do some logic and then insert the query looks like
insert into table (col1, col2, col3..) select val1,val1+val2,someOperation from table where id = x;
I think you need something like this :
IF( select count(*) from Table1 ) is null
begin
IF( select count(*) from Table1 ) is null
begin
--execute if condition is True
--insert condition
end
IF( select count(*) from Table1 ) is not null
begin
--execute if condition is False
--insert condition
end
end
MYSQL example :
IF ((select count(*) from table where id = x)) = 0
THEN
--insert into table (col1,col2..) values (val1, val2..)
ELSE
IF ((select count(*) from table where id = x)) != 0
THEN
--insert into table (col1, col2, col3..) select val1,val1+val2,someOperation from table where id = x;
END IF;
END IF;

How to create correct MySQL query INSERT

i have some data in the MySQL table like this:
2017-02-01: 'A': 'K1': 100
2017-02-01: 'A': 'K2': 200
2017-02-01: 'B': 'K1': 300
2017-02-02: 'A': 'K1': 110
2017-02-02: 'A': 'K2': 210
2017-02-02: 'B': 'K1': 310
i need to insert new data only if last (by date) value is not equal with new.
for example: insert new 400 if last [A:K1]<>400
i use 2 queries now for this job, but it's very slow to insert it:
$res=mysql_query("select * from `table` where `col1`='A' and `col2`='K1' order by 'date' desc limit 1");
$tkol=0;
if($res){while($r=mysql_fetch_assoc($res)){$tkol=$r[0]['col3']; break;}}
if($tkol!=$newVal){
$q="INSERT INTO `table` (`date`,`col1`,`col2`,`col3`) VALUES ('2017-02-10','A','K1',$newVal)";
mysql_query($q);
}
how to write my task in 1 mysql-query like "INSERT ... IF ..."?
Please, help me.
Try to use INSERT INTO SELECT syntax:
INSERT INTO `table` (`date`,`col1`,`col2`,`col3`)
SELECT DISTINCT '2017-02-10', 'A', 'K1', $newVal
FROM `table` t1
JOIN (
SELECT MAX(`date`) AS maxdate, `col1`, `col2`
FROM `table`
WHERE `col1` = 'A'
AND `col2` = 'K1'
) t2 ON t1.`col1` = t2.`col1` AND t1.`col2` = t2.`col2` AND t1.`date` = t2.`maxdate`
WHERE t1.`col1` = 'A'
AND t1.`col2` = 'K1'
AND t1.`col3` <> $newVal
use significant column as unique key and use REPLACE instead of INSERT.
OR
You can use insert ... from select ... where oldval <> newval;
select will not have "from" and values will be straightly written into it from webserver.
$q="INSERT INTO `table` (`date`,`col1`,`col2`,`col3`) select ".$date.", ".$a.", ".$b.", ".$c." WHERE not exists (select 1 from `table` where col1 = $a ... and date = select(max) date from table)";
And, remember about input validation!

SELECT user who has some values

Data
name 'chan' value 'a'
name 'chan' value 'b'
name 'max' value 'a'
name 'max' value 'b'
name 'tony' value 'a'
name 'tony' value 'c'
I need to find out user who both have value a and b, this is my solution:
SELECT * FROM `table`
GROUP BY `name`
HAVING SUM(IF(`value` = 'a', 1, 0)) >= 1 AND SUM(IF(`value` = 'b', 1, 0)) >= 1
Any better way?
Your solution is ok, but it would be better written as:
SELECT name
FROM `table`
GROUP BY `name`
HAVING SUM(`value` = 'a') >= 1 AND SUM(`value` = 'b') >= 1;
A possibly more efficient form is:
SELECT name
FROM `table`
WHERE value in ('a', 'b')
GROUP BY `name`
HAVING COUNT(DISTINCT value) = 2;
And, depending on your data structure and indexes and size, this could also be efficient:
select ta.name
from table ta join
table tb
on ta.name = tb.name and ta.value = 'a' and tb.value = 'b';
I prefer the methods using group by and having because they generalize to a more diverse set of conditions.
Try this out. a DISTINCT is required if name per value in not unique.
eg (COUNT(DISTINCT value) = 2)
SELECT name
FROM tableName
WHERE value IN ('a', 'b')
GROUP BY name
HAVING COUNT(*) = 2

Conditional insert query (Row count validation). (MYSQL)

I am trying to write a query that will count and compare the number of rows of two tables on two different databases. If they are equal then a record will be inserted into another table as 'Pass', else it will result in a 'Fail'.
I haven't been able to find any answers through google searches... Here is my query that isn't working:
select
case when
((select count(1) from db1.transaction) = (select count(1) from db2.transaction))
then
insert into db3.validation (test_result) values ('pass')
else
insert into db3.validation (test_result) values ('fail')
end;
You can do this by reversing the order. Do a single insert with a select choosing the value:
insert into db3.validation(test_result)
select (case when t1.cnt1 = t2.cnt2 then 'pass' else 'fail' end)
from (select count(1) as cnt1 from db1.transaction) t1 cross join
(select count(1) as cnt2 from db2.transaction) t2;
Note that I moved the subqueries from the case to a from clause, simply because I find them easier to read this way. You can keep them in the case if you prefer.

Update multiple rows from same table in mysql

Update a single column over multiple rows depending on the data from the same table.
update table1 set status=newtime
from (
select
case
when TIME_FORMAT( TIMEDIFF( ADDTIME( time_val, '120:00:00' ), NOW() ), '%Hh %im %ss')<0 then '4'
else '0'
end as newtime,
id as new_id
FROM table1
where id2='2'
and status='0'
)
where id=new_id
This is my query. Thanks in advance.
Edit:
This is an alternate query to achieve this. But it also gives me an error
update table1 set status=
(select
case when timeleft<0 then '4' else '0' end as something,
new_id
from
(
select
TIME_FORMAT( TIMEDIFF( ADDTIME( time_val, '120:00:00' ), NOW() ), '%Hh %im %ss') as newtime,
id as new_id
FROM
table1
where id2='2' and
status='0'
)
}
where id=new_id
"#1248 - Every derived table must have its own alias".
I cannot use alias as I am fetching two columns from the query. Any help would be great.
UPDATE statements have no FROM clause in MySQL syntax. However, you can JOIN table against the subquery.
UPDATE
table1 t1
JOIN (
select
case
when TIME_FORMAT( TIMEDIFF( ADDTIME( time_val, '120:00:00' ), NOW() ), '%Hh %im %ss')<0 then '4'
else '0'
end as newtime,
id as new_id
FROM table1
WHERE id2='2' AND status='0'
) tsub ON t1.id = tsub.new_id
SET status = tsub.newtime
It looks to me like you don't need to do any subquerying or joining at all. This should do what you want:
UPDATE table1
SET status = CASE WHEN TIME_FORMAT(TIMEDIFF(ADDTIME(time_val, '120:00:00'), NOW()), '%Hh %im %ss') < 0 THEN '4' ELSE '0' END
WHERE id2 = '2' AND status = '0'
In the query you wrote, your subquery will get back the new time_val and the id number of the row to update, for any rows that match the criteria id2 = '2' AND status = '0'. You will then update all those rows (that matched the above criteria) and set the status to the new time_val.
Instead of selecting them first, cut out the middle man and just update all rows that match that criteria with the new value. Your query will be faster and more straightforward.
Besides the simplified version (provided by #Travesty3), it seems you are using a whole bunch of date and time functions to test for a simple thing:
UPDATE table1
SET status = '4'
WHERE id2 = '2'
AND status = '0'
AND time_val < NOW() - INTERVAL 120 HOUR
We can update table with multiple row by same table or two different table in this manner, just posting a snippet of mysql code from my procedure
Update documentcolumns as tb1, documentcolumns as tb2 set tb1.documentColumnPos = tb2.documentColumnPos Where tb1.userID = user_id and tb2.userID is NULL and tb1.columnNameDefID= tb2.columnNameDefID and tb1.tabtype = tab_type and tb2.tabtype = tab_type;,