MySQL Update only changes - mysql

I've imported a file to a MySQL table and now I want to update an existing table only with the changes.
I'm trying this with a select first before doing it as an update.
Both tables have an unique id field and value fields.
The following query doesn't give any results although there are differences in the value field:
SELECT a.id, a.value, b.value FROM a, b WHERE a.id=b.id AND a.value!=b.value
When I try it with a.value=b.value it works, but I need the changes.
Any Ideas?
My goal is to update table a in the end with changed values from table b but I can't update everything because I don't want to change a "lastedit" field if there are no changes.
I can't change the structure of table a to an automatic "lastedit" field.

UPDATE a INNER JOIN b ON a.id = b.id
SET a.value = b.value
WHERE a.value <> b.value
;
But of course, this only updates anything if (as Marc B said in his comment above) the tables have corresponding id values.

Related

How to include a WHERE clause only when a field has a value?

I have two tables where A might have a related record in B. If it does, I want a field from B, and if not I just want data from A. I tried something like this:
SELECT A.field B.field
FROM A, B
WHERE (A.b_id = B.id OR A.b_id IS NULL)
If there's a related record in B, give me that field's contents. If not, I probably just want to get NULL instead.
Is this possible with MySQL, or do I need to get A's record first, see if A.b_id had a value and if so then get the data I want from B?
Use a left join:
SELECT A.field, B.field
FROM A
LEFT JOIN B ON A.b_id = B.id

Join/Update between Three Tables

Currently to get data updated in Table3 that depends on conditions in Tables1 and Table2 I am doing this:
Update Table_B as T1
Inner Join Table_A as T2
On T1.S_ID=T2.ID
Set T1.Percent = T2.Percent
Update Table_C as T1
Inner Join Table_B as T2
On T1.ID=T2.J_ID
Set T1.B = T2.B
Where T2.Percent=100
I would like to not store or update TableB with TableA Percent and somehow do the join in a single statement.
update table_b T1 set T1.Percent=(select T2.Percent from table_a T2 where T1.S_ID=T2.ID)
update table_c T1 set T1.B=(select T2.B from table_b T2 where T1.ID=T2.J_ID) where exists(select * from table_b T3 where T1.ID=T3.J_ID and T3.percent=100)
This isn't valid syntax in an UPDATE statement
Set T1.Percent as T1.Percent
^^
And this isn't valid
Set T1.B as T2.B
^^
The syntax in the UPDATE statements in the question do not look valid.
The SET assignment operator is an equals sign, not an As keyword.
And T1.Percent = T1.Percent doesn't make much sense, since there doesn't seem to be any point to setting a column to its current value.
It's not clear what it is you are actually trying to achieve, without some example data, and the desired end result.
To write a multi-table UPDATE statement, I first write a SELECT statement that returns the primary (or unique) keys of the tables that I am going to update, along with the current values of the columns to be updated, and expressions that return the new values that are going to be assigned to the columns
Based on the SQL in the question, it looks like you might want two joins, something like this:
SELECT ...
FROM table_a a
JOIN table_b b
ON b.s_id = a.id
JOIN table_c c
ON c.id = b.j_id
WHERE a.percent = 100
ORDER BY ...
(We don't know anything about the cardinality of the columns and relationships, whether those are one-to-one, one-to-many, zero-or-one-to-one, etc. We're just guessing.)
To evaluate and test the query, I'd include the primary keys of the tables. I'm going to guess id is the primary key of (the unfortunately named) Table_A and Table_C. And guess that the tuple (j_id,s_id) is a UNIQUE KEY in Table_B.
I will also include the column to be updated (to show the current value), and an expression that returns the new value to be assigned to the column.
Something like this:
SELECT a.id AS `a__id`
, a.percent AS `a__percent`
, b.j_id AS `b__j_id`
, b.s_id AS `b__s_id`
, c.id AS `c__id`
, c.b AS `c__b_old`
, b.b AS `c__b_new`
FROM table_a a
JOIN table_b b
ON b.s_id = a.id
JOIN table_c c
ON c.id = b.j_id
WHERE a.percent = 100
ORDER
BY c.id
, a.id
I would test that, and make sure it's returning the rows from Table_C that I want to update, and that the value returned for the c__b_new expression is the value that I want to assign to the b column in Table_C.
Once I get the SELECT statement working correctly (and only after I get it working correctly), I convert that to a multitable UPDATE.
Just replace the SELECT ... FROM part with the keyword UPDATE.
And before the WHERE clause, add a SET clause that does the assignment of the new value to the column. (I use the same expression I used in the SELECT list to return the new value.)
UPDATE table_a a
JOIN table_b b
ON b.s_id = a.id
JOIN table_c c
ON c.id = b.j_id
SET c.b = b.b
WHERE a.percent = 100
That's just an example of how I go about writing a multi-table UPDATE. There is no guarantee that this statement is going to work for what you need. Again, it's not clear what you are trying to achieve; the specification is too vague; so we're only guessing.

Update a field in table A with the max value of field in table B

I want to update a field, let's call it 'field_A', in table 'table_A' with the maximum value that exists of field 'field_B' in 'table_B', but only IF there is a max value for that field 'field_B' in table 'table_B'.
Table 'table_B' has a 'reference' field which contains the 'id' of the table_A record we want to update.
Now I have the following query, which works perfectly.
UPDATE table_A a SET a.field_A = (SELECT MAX(b.field_B)
FROM table_B WHERE b.reference = a.id)
WHERE a.id IN (
SELECT reference
FROM table_B
GROUP BY reference
HAVING COUNT(reference) > 0
)
So it only updates field_A IF there are records found for that reference because I don't want to end up setting fields 'field_A' to zero when no related records were found.
As I said before, this query already works perfectly, but now I have to run a query for table_B two times, which seems a little bit inefficient and it is probably possible to do it with only 1 join statement but I can't seem to tackle the issue.
Since this query has to cross reference a lot, really a lot, of records, performance is really an issue here.
With these two nested statements, your UPDATE statements seems quite
inefficient to me. Try this SQL statement below, that should do the job.
SQL Fiddle here: http://sqlfiddle.com/#!2/5825a/2
UPDATE table_A a1
JOIN
(
SELECT a.id as id, max(b.field_B) as max_val
FROM
table_A a
LEFT JOIN table_B b ON a.id = b.reference
GROUP BY a.id
) t on a1.id = t.id
SET
a1.field_A = t.max_val
WHERE
(t.max_val IS NOT NULL)

Mysql query with if exists check in where clause

I have two tables (A and B) where my query compares a calculation from table A with a range in table B and then insert a corresponding value to the range(also in table B) in the third table(table C) based on dates. However,it is a possibility that table A may not have data for everyday and for those days i want to enter the value against the second lowest range.
TABLE B
id(PK)|date| v1 | v2
TABLE A
Aid|id(FK)|MinRange|MaxRange|Value
TABLE C
Cid|b.date|id(FK)|b.v1|b.v2|A.value
I am looking for a way to embed IF EXISTS in the WHERE clause something like this:
SELECT B.value
from TableB B
INNER JOIN TableA A ON A.id=B.id
WHERE B.id=4
and (IF DATA EXISTS) B.v1+B.v2 between A.min and A.max (ELSE Choose the second lowest A.min)`
The query above is an example to explain what i am trying to do, hence, it is not a valid query. I do not want to use a subquery for obvious performance issues.
I will appreciate any help.Thanks in advance :)
What about this
UPDATE
DECLARE myvar INT;
SELECT COUNT(*) INTO myvar FROM TableB WHERE Date=p_date;
SELECT myvar;
IF(myvar>0)
SELECT B.Date,A.Value
from TableB B
left JOIN TableA A ON A.id=B.id
WHERE B.id=4
ELSE
SELECT p_date AS Date,predefinedvalue AS Value
END IF;
You have to use left join because inner join will retrieve only the matching records. Also the predefined value has to be stored in B since if there is no matching record you can't query anything from A.
SELECT CASE WHEN myvar>0 THEN B.Date
ELSE p_date
END AS Date,
CASE WHEN myvar>0 THEN A.Value
ELSE predefinedvalue
END AS Value
from TableB B
left JOIN TableA A ON A.id=B.id
WHERE B.id=4

mysql cross-updating a table

I can't figure out how to solve this problem.
I have a table (A) I need to update, with a structure like this:
CODE VALUE
1 a
2 null
3 null
etc...
Then I have another table (B) with the same structure but with every value set:
CODE VALUE
1 a
2 b
3 c
What I need to do is to copy data from table B to table A where A.CODE = B.CODE but only if A.VALUE is not set.
What's the best query to do so? Can't do it by hand since I'm dealing with 2000ish rows.
I wrote something like this but it doesn't seem to work:
update A set VALUE =
(select b.VALUEfrom B b, A a where b.CODE = a.CODE)
Thanks in advance!
UPDATE a SET a.Value = b.Value
FROM TableA a
INNER JOIN TableB b ON (a.CODE = b.CODE)
WHERE a.VALUE IS NULL
Check that a.VALUE is set to do the update, and only select from the B table in the inner clause (and use the value of A from the outer clause):
update A
set VALUE = (select B.VALUE from B where B.CODE = A.CODE)
where VALUE IS NULL;