MySQL: How to add a column for original_id? - mysql

I want to add a column original_id to existing table, for example table_1:
sub_id
next_sub_id
2
4
4
6
6
null
8
10
10
null
to table_2 as sub_id = 4 or sub_id = 6 belongs to the first one that sub_id = 2
and sub_id = 10 belongs to sub_id = 8
sub_id
next_sub_id
original_id
2
4
2
4
6
2
6
null
2
8
10
8
10
null
8
How can I query under MySQL? Thanks!

You can check this link for more detail information
sameple is like this
ALTER TABLE table
ADD [COLUMN] column_name column_definition [FIRST|AFTER existing_column];
then you can update the value in the new column
sample is like this
UPDATE [LOW_PRIORITY] [IGNORE] table_name
SET
column_name1 = expr1,
column_name2 = expr2,
...
[WHERE
condition];

You can use a recursive CTE for this:
with recursive cte as (
select sub_id, next_sub_id, sub_id as original_id, 1 as lev
from t
where not exists (select 1 from t t2 where t2.next_sub_id = t.sub_id)
union all
select t.sub_id, t.next_sub_id, cte.original_id, lev + 1
from t join
cte
on cte.next_sub_id = t.sub_id
)
select *
from cte
order by sub_id;
Here is a db<>fiddle.

Related

How to query update in sql based on data from other table

I Have 2 Tables.
As Example:
table1
ID, data_static1, name1
1 8 Muna
2 1 Andi
3 7 null
table2
ID, data_static2, name2
1 0 Aji
2 1 Andi
3 2 max
4 3 nadine
5 4 Rio
6 5 Panji
7 6 Eko
8 7 Pan
9 8 Muna
I want to update the column name1 in table1 based on the largest ID in table1 where table1.data_static1 is the same as table2.data_static2.
I want the results as below
table1
ID, data_static1, name
1 8 Muna
2 1 Andi
3 7 Pan
I've tried the following code
mysql> UPDATE theDB.table1 SET name1=(SELECT name2 FROM table2 WHERE data_static2=(SELECT data_static1 From table1 WHERE ID IN(SELECT MAX(ID) FROM table1))) WHERE table1.ID IN(SELECT MAX(table1.ID) FROM theDB.table1);
I get an error message
ERROR 1093 (HY000): You can't specify target table 'table1' for update in FROM clause
Simplest solution would be to use a correlated subquery for this:
update table1 t1
set name1 = (
select name2
from table2 t2
where t1.data_static1 = t2.data_static2
order by id desc limit 1
);
You can use JOIN too:
update table1 t1
join (
select *
from table2 t
join (
select data_static2,
max(id) as id
from table2
group by data_static2
) t2 using (data_static2, id)
) t2 on t1.data_static1 = t2.data_static2
set t1.name1 = t2.name2;

Use Order By, and Group by on a Union result from 2 different columns

This My Table
ID Value SenderID RecieverID
1 Hello There 2 7
2 etc etc 7 5
3 etc 2 6
4 ee 7 2
5 asdas 2 7
6 asdas 2 5
7 asdas 7 5
What I want is the value from either senderID or receiverID from all the rows in which a specific value let say 2 occurs in any of these 2 columns
I used this query
SELECT `SenderID` FROM `messages` WHERE `RecieverID` = 2
UNION
SELECT `ReceiverID` FROM `messages` WHERE `SenderID` = 2
Gives unique answer but in wrong order
like this
ReceiverID
7
6
5
I'm expecting the answer of this query to be ordered by ID DESC in which a specific sender or reciever id occures for example in my tables the msg between senderid 2 and reverid 7 is at id 5 and latest id btweend sendr2 and 6 is at id 3 and btweed sndr2 and 5 it is ID 7 sot the above answer should be sorted like this 5, 7, 6 instead of 7,6,5
This one will order the sender/receiver IDs by their most recent conversation:
SELECT senderID -- , MAX(ID) as maxID -- uncomment to see maxID
FROM (
SELECT ID, `SenderID` FROM `messages` WHERE `RecieverID` = 2
UNION ALL
SELECT ID, `RecieverID` FROM `messages` WHERE `SenderID` = 2
) as sub
GROUP BY (SenderID)
ORDER BY MAX(ID) DESC
http://sqlfiddle.com/#!9/6d7bc0/1
you need to use inner query in a brackets in order to set what the order by refers to:
SELECT id, senderID from
(SELECT ID, `SenderID` FROM `messages` WHERE `RecieverID` = 2
UNION
SELECT ID, `RecieverID` as senderId FROM `messages` WHERE `SenderID` = 2
) as A
GROUP BY (SenderID)
order by ID ASC
SELECT ID, IF(`SenderID` = 2,`RecieverID`,`SenderID`)
FROM `messages`
WHERE `RecieverID` = 2 OR `SenderID` = 2
group by IF(`SenderID` = 2,`RecieverID`,`SenderID`)
order by ID ASC

Update a column of a table with the count of other column in the same table in a MySQL server

I have a table like this:
recordid customerid product id count
1 2 12 3
2 4 10 1
3 2 3 3
4 3 12 2
5 3 10 2
6 2 7 3
7 5 3 1
8 ....
9 ....
I want an update query that will count the no of occurrence of each customer id and update the count column which will initially be empty.
the end result should be like above
The column names are dummy, my actual table is different.
It has data in millions of rows.The query should be speedy
I tried the query but it gets stuck...
update tablename, (select count(recordid) as count,customerid from tablename group by customerid) as temp set count=temp.count where customerid=temp.customerid
You can use JOIN in UPDATE.
Try this:
UPDATE TableName A
JOIN
(SELECT customerid,Count(customerid) as cnt
FROM TableName
GROUP BY customerid) as B ON A.customerid= B.customerid
SET A.count = B.cnt
This doesn’t see right:
update tablename, (select count(recordid) as count,customerid from tablename group by customerid) as temp set count=temp.count where customerid=temp.customerid
Why is there a comma after update tablename like this:
update tablename,
I am also reformatting for readability:
UPDATE tablename (
SELECT count(recordid) AS count, customerid
FROM tablename GROUP BY customerid
) as temp
SET count=temp.count
WHERE customerid = temp.customerid

Find duplicate records in MySQL without named column

I have a table like this:
**lead_id** **form_id** **field_number** **value**
1 2 1 Richard
1 2 2 Garriot
2 2 1 Hellen
2 2 2 Garriot
3 2 1 Richard
3 2 2 Douglas
4 2 1 Tomas
4 2 2 Anderson
Where field_number = 1 is the name and field_number = 2 is the surname.
I would like to find entries that are equal by name OR surname and group them by lead_id, so the output could be like this:
1
2
3
Any thoughts on how this can be done?
This should work and be reasonably efficient (depending upon indexes):
select distinct lead_id
from tablename as t1
where exists (
select 1
from tablename as t2
where t1.field_number = t2.field_number
and t1.value = t2.value
and t1.lead_id <> t2.lead_id
)
Select leadid from (
Select DISTINCT leadid,value from tablename
Where fieldnumber=1
Group by leadid,value
Having count(value) >1
Union all
Select DISTINCT leadid,value from tablename
Where fieldnumber=2
Group by leadid,value
Having count(value) >1
) as temp
Surely there is a faster option

MySQL Delete duplicates in consecutive rows

Suppose this table:
ID ColA ColB
1 7 8
2 7 9
3 7 9
4 5 8
5 6 9
6 6 9
7 5 4
The PK is the ID coumn.
Now, I want to delete all duplicates of ColA and ColB in consecutive rows.
In this example rows 2,3 and 5,6 contain duplicates.
These shall be removed so that the higher ID is remained.
The output should be:
ID ColA ColB
1 7 8
3 7 9
4 5 8
6 6 9
7 5 4
How can this be done with mySQL?
Thanks,
Juergen
SELECT
ID
FROM
MyTable m1
WHERE
0 < (SELECT
COUNT(*)
FROM
MyTable m2
WHERE
m2.ID = m1.ID - 1 AND
m2.ColA = m1.ColA AND
m2.ColB = m1.ColB)
and then you can use a
delete from MyTable where ID in ...
query. This way it would surely work in any version.
CREATE TEMPORARY TABLE duplicates (id int primary key)
INSERT INTO duplicates (id)
SELECT t1.id
FROM table t1
join table t2 on t2.id = t1.id + 1
WHERE t1.ColA = t2.ColA
and t1.ColB = t2.ColB
-- SELECT * FROM duplicates --> are you happy with that? => delete
DELETE table
FROM table
join duplicates on table.id = duplicates.id
Depending on how many records you have, this might not be the most efficient:
SELECT (SELECT TOP 1 id FROM table WHERE colA = m.colA AND colB = m.colB ORDER BY id DESC) AS id, m.*
FROM (SELECT DISTINCT colA, colB
FROM table) m
There might be syntax errors because I usually use mssql, but the idea should be similar.
I've called the first table 'test'.
Firstly create a table that will hold all the identical combinations of ColA and ColB:
create temporary table tmpTable (ColA int, ColB int);
insert into tmpTable select ColA,ColB from test group by ColA, ColB;
Now, select the maximum id in the original table for each identical combination of ColA and ColB. Put this into a new table (called idsToKeep because these are the rows we do not want to delete):
create temporary table idsToKeep (ID int);
insert into idsToKeep select (select max(ID) from test where test.ColA=tmpTable.ColA and test.ColB=tmpTable.ColB) from tmpTable;
Finally, delete all the entries from the original table that are not in the idsToKeep table:
delete from test where ID <> all (select ID from idsToKeep);