Update table with random values from another table without duplicates in MySQL - mysql

I want to update a column in a MySQL table that contains string values with values from another table that contains unique names, but without repeating the same values.
Each name in the 'names' table has a unique id from 1 - 1001.
There are 161 names in the target table.
I tried something like this, but it fetches duplicate entries:
UPDATE table_to_update
SET name =
( SELECT name FROM `names`
WHERE id >= (SELECT FLOOR(RAND()*(SELECT MAX(id) FROM `names`)) )
LIMIT 1 ) ;

Here is one option if you are using MySQL 8+, which supports ROW_NUMBER:
UPDATE table_to_update t1
INNER JOIN
(
SELECT id, ROW_NUMBER() OVER (ORDER BY id) rn
FROM table_to_update
) t2
ON t1.id = t2.id
INNER JOIN
(
SELECT name, ROW_NUMBER() OVER (ORDER BY id) rn
FROM (SELECT name, id FROM names ORDER BY RAND() LIMIT 161) t
) t3
ON t2.rn = t3.rn
SET
t1.name = t3.name;
Note that I hard-coded the LIMIT value to be 161 in the subquery, given that you know the size of the target table. This value could be made dynamic as well, but would require more work.

Related

Deleting duplicate values from a mysql table but keep one

I'm trying to delete duplicate rows from a mysql table, but still keep one.
However the following query seemingly deletes every duplicate row and I'm not sure why. Basically I want to delete the row if the outputID, title and type all matches.
DELETE DupRows.*
FROM output AS DupRows
INNER JOIN (
SELECT MIN(Output_ID) AS Output_ID, Title, Type
FROM output
GROUP BY Title, Type
HAVING COUNT(*) > 1
) AS SaveRows
ON SaveRows.Title = DupRows.Title
AND SaveRows.Type = DupRows.Type
AND SaveRows.Output_ID = DupRows.Output_ID;
Just :
DELETE DupRows
FROM output AS DupRows
INNER JOIN output AS SaveRows
ON SaveRows.Title = DupRows.Title
AND SaveRows.Type = DupRows.Type
AND DupRows.Output_ID > SaveRows.Output_ID
This will delete all duplicates on Title and Type while keeping the record with the lowest value.
If you are running MySQL 8.0, you can use window function ROW_NUMBER() to assign a rank to each record in Title/Type groups, ordered by id. Then you can delete all records whose row number is not 1.
DELETE FROM output
WHERE Output_ID IN (
SELECT Output_ID
FROM (
SELECT Output_ID, ROW_NUMBER() OVER(PARTITION BY Title, Type ORDER BY Output_ID) rn
FROM output
) x
WHERE rn > 1
)
Delete From output Where Output_ID NOT IN (
Select MIN(Output_ID) from output Group By Title, Type Having COUNT(*)>1
)
By below query duplicate rows with matching condition get deleted and keeps one oldest unique row.
NOTE:- In my query I used id column is auto increment column.
DELETE t1
FROM output t1, output t2
WHERE t1.Title = t2.Title
AND t1.Type = t2.Type
AND t1.Output_ID = t2.Output_ID
AND t1.id>t2.id
If you want to keep newly inserted unique row just change the last condition as:
DELETE t1
FROM output t1, output t2
WHERE t1.Title = t2.Title
AND t1.Type = t2.Type
AND t1.Output_ID = t2.Output_ID
AND t1.id<t2.id

How can I do own increment value in mysql

I'm struggling to do proper sql script to increment field on specific way.
Those two script are without any exception, but nothing happened on the results.
Script 1:
UPDATE
myTable T1,
(
SELECT id,
(#s:=#s+1) AS seq
FROM myTable, (SELECT (#s:=0) AS s ) s
WHERE infotext IS NULL ORDER BY grouptext
) T2
SET sequence = seq
WHERE T1.id = T2.id
Script 2:
UPDATE myTable AS target
INNER JOIN (
SELECT supfault_id,
(#s:=#s+1) AS seq
FROM myTable, (SELECT (#s:=0) AS s ) s
WHERE infotext IS NULL ORDER BY grouptext
) AS ordered ON ordered.id = target.id
SET sequence = seq
This one get the last desc value from table1 and increment by one then update the table2:
set #inc = 0;
select cast(valToIncrement as signed) into #inc from
(select REPLACE(fkid,' ','') as valToIncrement from tbl_1 ORDER BY fkid)as a ORDER BY valToIncrement desc limit 1;
update tbl_2 set fkid = #inc + 1 where fkid = 122;
Subqueries working well separately, so I wondered why I can't update my sequence value by seq from subquery.
I'm not expert, but I felt that need to be used some virtual table for my subquery.
Here is solution for inner join case:
CREATE TEMPORARY TABLE supportGroupSeqcalculation AS
SELECT supfault_id,
(#s:=#s+1) AS seq
FROM myTable, (SELECT (#s:=0) AS s ) s
WHERE infotext IS NULL
ORDER BY grouptext;
UPDATE myTable AS target
INNER JOIN supportGroupSeqcalculation AS ordered ON ordered.supfault_id = target.supfault_id
SET sequence = seq;
DROP TEMPORARY TABLE supportGroupSeqcalculation;
We can get into temporary table specific order and record it as sequence value.
It is not necessarily to drop temporary table, it exists only in current session.

Delete records from a table where < max number for a field and keep highest number

I know this sounds rather confusing but I'm at a loss how to explain it better. I have a table simplified below:
DB Type ID
================
Table1 1
Table1 2
Table1 3
Table1 4
Table1 5
Table2 6
Table2 7
Table2 8
Table2 9
Table2 10
what i am trying to achieve is to basically clean out this table but keep the record with the highest ID for each DB Type if that makes sense - so in this case it would be (Table1,5) and (Table2,10) with all other records being deleted. Is it possible to do this exclusively through MySQL?
*EDIT***
Answer thanks to tips from Yogendra Singh
DELETE FROM MyTable WHERE ID NOT IN (SELECT * FROM (SELECT MAX(ID) from MyTable GROUP BY DB Type) AS tb1 ) ORDER BY ID ASC
TRY selecting the max ID group by db_type first and then use it as sub query with not in.
DELETE FROM MyTable
WHERE ID NOT IN
(SELECT ID FROM
(SELECT MAX(ID) AS ID from MyTable GROUP BY DB Type) AS tb1
)
EDIT:
DELETE FROM MyTable
HAVING MAX(ID) > ID;
delete your_table
from
your_table left join
(select max(id) max_id from your_table group by type) mx
on your_table.id=mx.max_id
where mx.max_id is null
Subquery returns the maximum id for every type, and those are the values to keep. With an left join i'm selecting all the rows from your table that don't have an in in max_ids, and those are the rows to delete. This will work only if id is primary key, otherwise we have to join also the type.
Is the combination DB Type - ID unique?
If so, you can attack this in two stages:
Get only the rows you want
SELECT [DB Type], Max(ID) AS MaxID
FROM YourTable
GROUP BY [DB Type]
Delete the rest (Wrapping the previous statement into a more complicated statement; don't mean that)
DELETE FROM YourTable
FROM
YourTable
LEFT JOIN
(SELECT [DB Type], Max(ID) AS MaxID
FROM YourTable GROUP BY [DB Type]) DontDelete
ON
YourTable.[DB Type]=DontDelete.[DB Type] AND
YourTable.ID=DontDelete.MaxID
WHERE
DontDelete.[DB Type] IS NULL
DELETE FROM MyTable del
WHERE EXISTS (
(SELECT *
FROM MyTable xx
WHERE xx."db Type" = del."db Type"
AND xx.id > del.id
);
delete from my_Table
where Day in (select MAX(day) d from my_Table where id='id')

Confused with UPDATE query. How to convert select to update with MySQL?

I have seen very similar if not same questions on here but my trials of trying to convert following query into an UPDATE statement failed.
SELECT table.* FROM table JOIN (
SELECT column, COUNT(*) AS rank
FROM table
GROUP BY column
) AS t USING (column) WHERE t.rank = 1
ORDER BY t.rank DESC
I want to update column of all results selected using the query above.
How can I convert this into an update statement?
Thank you.
This should do it:
update table
set column = 'somevalue'
where id in
(select id from (
SELECT table.* FROM table JOIN (
SELECT column, COUNT(*) AS rank
FROM table
GROUP BY column
) AS t USING (column) WHERE t.rank = 1) x)
not entirely sure but i think it's something like
update tblname set columname = value where tblname.columncompare = (select statement)
INSERT INTO table (id, value)
SELECT table.id, table.value
FROM table
JOIN (
SELECT column, COUNT(*) AS rank
FROM table
GROUP BY column
) AS t USING (column)
WHERE t.rank = 1
ORDER BY t.rank DESC
ON DUPLICATE KEY UPDATE value = VALUES(value)
Insert on duplicate to the rescue!
Basicly this allows you to do any SELECT as normal and then you prepend INSERT INTO and append ON DUPLICATE.
I guess that this query is made up, but what's the point of filtering and ordering the same column?

How to use distinct and limit together

I have a mysql query. I need to get last value from columns Lat,Lng from my table but serial_number column needs to be distinct.
How to make such a query?
This is needed as I am using this coordinates to load it to Google map. So when the Google maps loads I need to have a marker on each last coordinates where vehicle is.
SELECT m.*
FROM (
SELECT DISTINCT serial_number
FROM mytable
) md
JOIN mytable m
ON m.id =
(
SELECT id
FROM mytable mi
WHERE mi.serial_number = md.serial_number
ORDER BY
mi.time DESC, mi.id DESC
LIMIT 1
)
Create an index on (serial_number, time, id) for this to work fast.
If you want to retrieve the last record for a certain serial_number, just use this:
SELECT *
FROM mytable
WHERE serial_number = :my_serial_number
ORDER BY
time DESC, id DESC
LIMIT 1
1#
Assuming that max ID will always give you last lat and lon, the query becomes quite simple -
SELECT t2.*
FROM table t2
where t2.id IN
(
SELECT max(t1.id)
FROM table t1
GROUP BY t1.serial_number
)
2#
If you need to consider time also, then you will need to do it this way. Here, in the inner query, max_time of each serial_number is obtained. Then this max_time and serial_number is joined with the outer table time and serial_number respectively, to get distinct records with last lat and lon.
SELECT *
FROM table t2,
(
SELECT max(t1.time) max_time, t1.serial_number
FROM table t1
GROUP BY t1.serial_number
) new_table
WHERE t2.time=new_table.max_time
AND t2.serial_number=new_table.serial_number
Try this
select distinct serial_number, *
from table t
inner join table t1 on t1.serial_number = t.serial_number and t1.id = (select max id from table t2 where t2.serial_number = t1.serial_number)