How to update value in same table using mysql? - mysql

I need to replace/update values in my table according att_id for each customer_id.
The table looks like:
ID att_id customer_id value
1 5 1 name
2 30 1 12345
3 40 1
4 5 2 name2
5 30 2 12345
6 40 2
I'd like to replace it like this:
ID att_id customer_id value
1 5 1 name
2 30 1
3 40 1 12345
4 5 2 name2
5 30 2
6 40 2 12345

UPDATE: Based on your comments ...I need to find values for attribute 30, check if they are mobile phone numbers, and if it's true, write it itno value for attribute 40... your query might look like this
UPDATE table1 t1 JOIN table1 t2
ON t1.customer_id = t2.customer_id
AND t1.att_id = 40
AND t2.att_id = 30
SET t1.value = t2.value
-- ,t2.value = NULL -- uncomment if you need to clear values in att_id = 30 at the same time
WHERE t2.value REGEXP '^[+]?[0-9]+$'
You might need to tweak a regexp to match your records ("mobile phone numbers") properly
Here is SQLFiddle demo
It's hard to tell for sure from your description but if you need to swap values of att_id 30 and 40 per customer_id you may do something like this
UPDATE table1 t1 JOIN table1 t2
ON t1.customer_id = t2.customer_id
AND t1.att_id = 40
AND t2.att_id = 30
SET t1.value = t2.value,
t2.value = t1.value
Here is SQLFiddle demo
or if you need to put values of att_id = 30 to att_id = 40 and "clear" values of att_id = 30
UPDATE table1 t1 JOIN table1 t2
ON t1.customer_id = t2.customer_id
AND t1.att_id = 40
AND t2.att_id = 30
SET t1.value = t2.value,
t2.value = NULL
Here is SQLFiddle demo

Here is a general approach for swapping the values on rows with att_id equal to 30 and 40:
update t join
t t30
on t.customer_Id = t30.customer_Id and t30.att_id = 30 join
t t40
on t.customer_Id = t40.customer_Id and t40.att_id = 40 join
set t.value = (case when att_id = 30 then t40.value
when att_id = 40 then t30.value
else t.value
end)
where att_id in (30, 40);

First, you remove the value of att_id = 30
UPDATE tablename SET value="" WHERE att_id=30;
Then set the value for att_id=40
UPDATE tablename SET value="12345" WHERE att_id=40;

UPDATE tableName SET value=12345 WHERE ID=2;
UPDATE tableName SET value="" WHERE ID=3;
UPDATE tableName SET value=12345 WHERE ID=6;
UPDATE tableName SET value="" WHERE ID=5;
This are the command .See http://www.tutorialspoint.com/mysql/mysql-update-query.htm for tutorial on update.

Related

Updating table based on same table with a max value

Have a table data structure like below:
id
regid
docid
archived
1
1000
1
0
2
1000
2
0
3
1000
3
0
4
2000
1
0
5
2000
2
0
6
3000
1
0
7
3000
2
0
8
3000
3
0
9
3000
4
0
What I'm trying to do update the archived column to 1 where the docid is less than the max docid, by each regid group.
So I should end up with id's 3, 5 & 9 not being set to 1
Have tried:
update table t1
join (select max(docid) as maxdocid, regid from table) t2 on t1.docid < t2.maxdocid and t1.regid = t2.regid
set t1.archived = 1
But doesn't work, only does the first regid group.
Here's a solution (in MySQL 8.0+) using a CTE:
WITH numbered_table AS (
SELECT id, ROW_NUMBER() OVER (PARTITION BY regid ORDER BY docid DESC) AS rownum
FROM mytable
)
UPDATE mytable JOIN numbered_table USING (id)
SET archived = 1
WHERE rownum > 1
AND archived = 0;
Second solution, if you use an older version of MySQL that doesn't support CTE syntax:
You don't really need to compute the max docid value. If you want to update all rows except for the row with the max docid value, then you can check if a row can be matched to any other row with a greater docid value.
UPDATE mytable AS t1
INNER JOIN mytable AS t2 ON t1.regid = t2.regid AND t1.docid < t2.docid
SET t1.archived = 1
WHERE t1.archived = 0;
This will be true for all rows except the row with the max value. That row will be excluded automatically by the join.
In steps:
Create a query with the MAX value, per docid:
SELECT
ID,
regid,
docid,
(SELECT MAX(docid) FROM t1 te where te.regid=t.regid) as M
FROM t1 t
Join the result, and update:
UPDATE t1
JOIN (
SELECT
ID,
regid,
docid,
(SELECT MAX(docid) FROM t1 te where te.regid=t.regid) as M
FROM t1 t
) x ON t1.id=x.id
SET archived = 1
WHERE t1.docid<x.M AND t1.archived=0;
see: DBFIDDLE
You could try:
update test_tbl t1
set t1.archived = 1
where t1.archived = 0
and t1.id not in ( select t2.id
from (select max(id) as id,
regid,
max(docid)
from test_tbl
group by regid
) as t2
) ;
Result:
id regid docid archived
1 1000 1 1
2 1000 2 1
3 1000 3 0
4 2000 1 1
5 2000 2 0
6 3000 1 1
7 3000 2 1
8 3000 3 1
9 3000 4 0
Demo
Or you can use a LEFT JOIN
update test_tbl t1
left join ( select max(id) as id,
regid,
max(docid) as docid
from test_tbl
group by regid
) as t2 on t1.id=t2.id
set t1.archived = 1
where t1.archived = 0
and t2.id IS NULL
Demo
Use a self join in the update statement:
UPDATE tablename t1
INNER JOIN tablename t2
ON t2.regid = t1.regid AND t2.docid > t1.docid
SET t1.archived = 1;
See the demo.

How to select All the rows from first table and get count of all the matching rows from other table for each row retrived from first table

Following are the tables
Table 1
price col1 col2 time
10 1 1 10
100 1 1 13
150 1 1 15
Table 2
id startTm endTm col1 col2
1 12 20 1 1
2 15 26 1 1
3 11 13 1 1
I want all the rows from table 2 satisfying startTm >= x and endTm <= y. And for each row in result I want to find count of all the records in table 1 where table1.time lies in startTm and endTm for that particular row
Something like this-
SELECT (#sTime:=T2.startTm) AS startTm,JT.totalNo, JT.totalPrice,
(#eTime:=T2.endTm) AS endTm
some more columns FROM table 2 AS T2
LEFT JOIN (SELECT COUNT(id) AS totalNo,col1, col2 SUM(price) AS
totalPrice FROM table 1 WHERE time BETWEEN #sTime AND #eTime GROUP
BY col1, col2)
AS JT ON JT.col1 = T2.col1
WHERE T2.startTm >= some value AND T2.endTm <= some value.
There are no related foreign keys.I Am not getting proper results. How is it done?
Edit
I want all the records from table 2 within specified time range suppose startTm >= 10 to endTm<=20
so output table will be
startTm endTm totalNo totalPrice some more col
12 20 2 250 ...
11 13 1 100 ...
to calculate total Price and total number I want to consider startTm and endTime of that particular row.
Is this what you want?
SELECT startTm, endTm, COUNT(price), SUM(price), t3_others, t1_others
FROM
(
SELECT T3.startTm AS startTm, T3.endTm AS endTm, T3.others AS t3_others, T1.price AS price, T1.others AS t1_others
FROM T1
RIGHT JOIN
(
SELECT T2.startTm, T2.endTm, T2.others
FROM T2
WHERE T2.startTm >= 10 AND T2.endTm <= 20 AND T2.col1 = col1_value AND T2.col2 = col2_value
) AS T3
ON T1.time >= T3.startTm AND T1.time <= T3.endTm
) AS T4
GROUP BY startTm, endTm;
Add other more fields as you need.
Try Following Query:
Select t1.* , t2.* from Table 1 as t1 RIGHT JOIN Table 2 as t2 ON t1.col1 = t2.col1 WHERE t2.startTm >= 'your value' AND t2.endTm <= 'your value'

Mysql delete duplicate rows + sort condition

I'm trying to delete some rows from my Mysql table, when one key is duplicate (here "url") and keep a particular one (here the smallest "key1" and "key2")
Example :
Table t1
Id Url Key1 Key2
1 A.com 10 10
2 B.com 20 25
3 B.com 21 25
4 C.com 35 35
5 C.com 35 37
Desired output is :
Table t1
Id Url Key1 Key2
1 A.com 10 10
3 B.com 21 25
5 C.com 35 37
So the query (if it exists) should look like :
Select rows where Url are duplicate
Then sort by Key1 and remove the row where Key1 is strictly inferior
if Key1 are equal, remove the row where Key2 is inferior
Thanks
You want to keep the rows where key1, key2 are maximal. An easy way to express this is:
delete t1 from table t1
where exists (select 1
from t1 t11
where t11.url = t1.url and
(t11.key1 > t1.key1 or
t11.key1 = t1.key1 and t11.key2 > t1.key2
)
);
Alas, MySQL doesn't allow this construct, because you using the table being deleted. So, you can do something like this:
delete t1
from t1 left join
(select t.*,
(select max(key2)
from t1
where t1.url = t.url and t1.key = t.maxkey1
) as maxkey2
from (select url, max(key1) as maxkey1
from t1
group by url
) t
) t
on t1.url = t.url and t1.key1 = t.maxkey1 and t2.key2 = t.maxkey2
where t.url is null;
I think this might be helpful
DELETE t1
FROM t1 as tb1
join t1 as tb2
WHERE tb1.url= tb2.url
and tb1.id < tb2.id
This way you keep the record with the max value on id column
but if you just want to fetch records
SELECT distinct tb1.*
FROM t1 as tb1
join t1 as tb2
WHERE tb1.url= tb2.url
and tb1.id < tb2.id

Column calculated by column with grouping

I have a simple table -
id | date | type | value
-------------------------
1 1/1/14 A 1
2 1/1/14 A 10
3 2/1/14 A 10
4 2/1/14 A 15
5 2/1/14 B 15
6 2/1/14 B 20
I would like to create a new column which calculates the minimum value per day per type. So giving the following results -
id | date | type | value | min_day
-----------------------------------
1 1/1/14 A 1 1
2 1/1/14 A 10 1
3 2/1/14 A 10 10
4 2/1/14 A 15 10
5 2/1/14 B 15 15
6 2/1/14 B 20 15
Is this possible? If so how would I go about it? I've been looking into triggers.
Thanks for any help.
First create a field named min_day in your table. Then you can use JOIN in an UPDATE query.
Try this:
UPDATE TableName T1 JOIN
(SELECT date,type,MIN(value) as MinValue
FROM TableName
GROUP BY type,date) T2 ON T1.type=T2.type AND T1.date=T2.date
SET T1.min_day = T2.MinValue
An example in SQL Fiddle.
EDIT:
For day-wise grouping:
UPDATE TableName T1 JOIN
(SELECT MONTH(date) as mon,type,MIN(value) as MinValue
FROM TableName
GROUP BY type,MONTH(date)) T2 ON T1.type=T2.type AND MONTH(T1.date)=T2.mon
SET T1.min_day = T2.MinValue
Result in SQL Fiddle.
Assuming that your table's name is mytable, try this:
SELECT mt.id,
mt.date,
mt.type,
mt.value,
mt.min_day,
md.min_value
FROM mytable mt
LEFT JOIN
(SELECT date, MIN(value) min_value FROM mytable GROUP BY DATE
) md
ON mt.date=md.date;
SELECT t1.*,
t2.min_day
FROM Table1 AS t1
JOIN
(SELECT date,TYPE,
min(value) AS min_day
FROM table1
GROUP BY date,TYPE) AS t2 ON t1.TYPE = t2.TYPE
AND t1.date = t2.date

Mysql Update based on existence in other table

I'm trying to figure out how to mass update a mysql table based on if a value exists in a column in another table.
e.g. pseudo code:
if Table1.`col`=Table2.`col` then
Update Table1.`status`=1
or
if table2.`col` exists in table1.`col`
Update Table1.`status`=1
What's the best way to achieve this?
Try this one -
UPDATE table1 t1
JOIN table2 t2
ON t1.col = t2.col
SET t1.status = 1;
Table 1
col | status
-------------
jaga | 0
kala | 0
Table 2
col | status
--------------
jaga | 1
latha | 0
If Table1.col=Table2.col // So this point is fullfill jaga record.
then Update Table1.status=1 // So Table 1 jaga row status want to Update in 1.
Is I am Correct?.
Then Try
UPDATE Table1 AS t1, Table2 AS t2 SET t1.col = 1 WHERE t1.col = t2.col
Happy Codings,
update t_checkout A
INNER JOIN t_target B on A.Media_ID = B.Media_ID
set A.status = 'R'
where A.Media_ID = 45
and exists (select * from t_target where B.Media_ID = 45 and status = 'R');
The 45 is hard coded here, but the value actually comes from a php parameter.