MySQL: update columns in the table based on criteria - mysql

I have this query
SELECT *, min(id)
FROM mytable
WHERE col2='specval'
GROUP BY col3
that selects rows I need.
I would like to set
UPDATE mytable
set col4 = col3+1000
for the rows selected above respectively.
So, how to update that rows by setting col4 in that table as col4=col3+1000 only for each selected row respectively?
Thank you.

you can use a query like this:
UPDATE mytable
set col4 = col3+1000
WHERE id in (
SELECT * FROM (
SELECT min(id)
FROM mytable
WHERE col2='specval'
GROUP BY col3
) as myids
);

You can use UPDATE with JOIN:
UPDATE mytable t1
INNER JOIN
(SELECT
col3, MIN(id) id
FROM
mytable
GROUP BY col3) t2 ON t1.col3 = t2.col3 AND t1.id = t2.id
SET
t1.col4 = t1.col3 + 1000;

You can use WHERE in update clause too. So depending on what "selected" means to you ( I'm guessing from your SELECT ), you might do something like this:
UPDATE mytable
SET col4 = col3+1000
WHERE col2 = 'specval';

Related

Update table with value from the same table using a sub query

I using sqlite and have a table that looks like:
I am trying to update refer column with values from col2 corresponding col1
I tried query like
update tab1
set refer = (select col2 from tab1 where col1 = refer)
where col1 = 2
This but is not working.
I have also tried
update tab1
set refer = (select tem1.col2
from tab1 tem1, tab1 tem2
where tem1.col1 = tem2.refer and tem2.col1=2)
where col1 = 2
This works.
But I am not sure whether this is the correct way to do.
Expected
Looking to your code seesm tha you need
update tab1
set refer = col2
when col1 = refer
and col1 = 2
that mean
update tab1
set refer = col2
when refer 2
oherwise fi yoru are looking for an update on the same table with subquery you should could use an inner join
in mysql
update tab1
INNER JOIN (
select col1, col2
from tab1
where col1 = refer ) t t.col1 = tabl1.col1 and col1 = 2
in sqllite you could use
update tab1
set refer = (select t.col2 from (
select col2 from tab1 where col1 = refer
) t )
where col1 = 2
Finally this query works perfectly:
update tab1
set refer = (select t1.col2 from tab1 as t1 where t1.col1 = tab1.refer)
where tab1.col1 = 2

mysql storing subquery in column and performing where condition

i am performing a sub query in mysql which is like
select col1, col2 , (select col3 from table2) as 'data'
from table1
where not data is null
how should i get data in where clause. IS it POSSIBLE
One way to do this is :
SELECT *
FROM (
select col1, col2 , (select col3 from table2) as 'data'
from table1
)t
WHERE data IS NOT NULL
As you see there I have created on derived table t for your query, now result of your query is treated as Table(temp table) and having columns as col1,col2 and col3, Using this result set we can able to access col3 in where clause .
Note - assuming that select col3 from table2 returns single value as per OP's comments
Use cross join:
select t1.col1, t1.col2, t2.col3 as data
from table1 t1 cross join
(select col3 from table2) t2
where t2.col3 is not null;

MySQL count on Grouping

I want to count the number of times a grouping occurs in a query.
SELECT COL1,
COL2,
*(count COL1)*
FROM TABLE
GROUP BY COL1, COL2
So I'm expecting to see the results like so:
COL1, COL2, Count
A, A, 1
A, B, 2
B, A, 1
B, B, 2
B, C, 3
Count(*) will give me the sum of the grouped row which is what I don't want, but I just cant seem to get my head round it or find a way to do it. Anyway, thanks in advance.
You should add auto_increment column to make an order. After that, try something like this:
SELECT a.col1, a.col2,
(SELECT Count(*) From T1 c
WHERE c.col1 = a.col1
AND c.ID <= a.ID) as count
FROM T1 a;
SQL Fiddle
OR Without auto_increment Try this:
SELECT col1, col2,
(select count(*) from T1 t2
where t2.col2 <= t1.col2 and
t2.col1 = t1.col1
) as Enumeration
FROM T1 t1
GROUP BY col1, col2;
SQL Fiddle
Your query (with the parentheses appropriately placed) does what you want:
SELECT COL1, COL2, count(*)
FROM TABLE
GROUP BY COL1, COL2;
If you want the sum of a column, then use the sum() function.
EDIT:
If you are trying to enumerate the groups (despite what the question is asking in rather clear English), you can do:
SELECT col1, col2,
(select count(*)
from table t2
where t2.col1 = t.col1 and
t2.col2 <= t.col2
) as Enumeration
FROM table t1
GROUP BY col1, col2;

MySQL Query - not interested in using inner query

I have a query say,
select col1,col2 from table1;
which return 2 columns of multiple rows. I want to use these two values in where condition of another query. Something like
select col3,col4 from table2 where col5=col1 and col6=col2;
where col1 and col2 are the resultant values of the first query.
Currently I have used inner query something like
select col3,col4 from table2
where col5 in (select col1 from table1)
and col6 in (select col2 from table1);
But I dont want to use inner query like the one shown above as it slows down bring results.
Please suggest.
JOIN them instead of using IN's like so:
SELECT t2.col3, t2.col4
FROM table2 t2
INNER JOIN
(
SELECT col1, col2
FROM table1
) t1 ON t2.col5 = t1.col1 AND t2.col6 = t1.col2
Note that, you didn't need to select specific columns in the second table. You can JOIN the second table table1 directly like so:
SELECT t2.col3, t2.col4
FROM table2 t2
INNER JOIN table1 t1 ON t2.col5 = t1.col1
AND t2.col6 = t1.col2

In MySQL (5.1) what is best way to detect one set of columns is not equal to another

I have two tables a source and a destination. I want to flag the destination table to be updated if any of the corresponding columns in source columns are different. The columns can be null.
Currently this seems very clumsy:
UPDATE destination d
JOIN source s
ON d.id = s.id
SET d.updateFlag = 1
WHERE ( (d.col1 IS NULL AND s.col1 IS NOT NULL)
OR (d.col1 IS NOT NULL AND s.col1 IS NULL)
OR (d.col1 <> s.col1)
)
OR
( (d.col2 IS NULL AND s.col2 IS NOT NULL)
OR (d.col2 IS NOT NULL AND s.col2 IS NULL)
OR (d.col2 <> s.col2)
)
...etc...
OR
( (d.colN IS NULL AND s.colN IS NOT NULL)
OR (d.colN IS NOT NULL AND s.colN IS NULL)
OR (d.colN <> s.colN)
)
Ideally I could do something like:
UPDATE destination d
JOIN source s
ON d.id = s.id
SET d.updateFlag = 1
WHERE HASH(d.col1,d.col2,...etc...,d.colN) <> HASH(s.col1,s.col2,...etc...,s.colN)
Some additional info. The columns are all different data types (some ints, some bits, some strings) and we are using a flavor of MySQL 5.1.
You can simplify your statement by using the NULL-safe equal to operator:
UPDATE destination d
JOIN source s
ON d.id = s.id
SET d.updateFlag = 1
WHERE !(d.col1 <=> s.col1)
OR !(d.col2 <=> s.col2)
...etc
As an alternative, you can use a UNION to find duplicate rows:
SELECT tbl, id, col1, col2, col3
FROM (
SELECT 't1' AS tbl, id, col1, col2, col3
FROM t1
UNION ALL
SELECT 't2' AS tbl, id, col1, col2, col3
FROM t2
) tmp
GROUP BY id, col1, col2, col3 HAVING COUNT(*) = 1;
You can then use the result from that in your update query:
UPDATE destination d
SET d.updateFlag = 1
WHERE EXISTS (
SELECT NULL FROM (
SELECT id, col1, col2, col3 FROM t1
UNION All
SELECT id, col1, col2, col3 FROM t2
) tmp
WHERE d.id = tmp.id
GROUP BY id, col1, col2, col3
HAVING COUNT(*) = 1
)
You might want to check out mk-table-checksum, which is one of the tools in Maatkit. This does what you're describing, calculating a checksum for the entire row and comparing it to the corresponding row in another database.
Many people use this tool to verify that a slave is a true replica of its master, but you can compare any two databases that have similar metadata.