Find duplicates based on two fields and delete them - mysql

I have a table called tourn_results there are multiple records that share the same tournamentId.
Example of a tourn_result record set
uniqueId tournamentId playerRank
1 111 1
2 111 2
3 111 3
4 222 1
5 222 2
6 222 3
7 333 1
8 333 2
9 333 3
10 333 4
11 111 1
12 111 2
13 111 3
For each tournament there cannot be more than 1 playerRank = 1
(Only one first place per tournamentId)
I need to to find each duplicate and delete them, can't find a suitable answer. I appreciate your help.

This will delete everything but the rows with the lowest uniqueid for each combination of (tournamentId,playerRank).
delete from tourn_results x
where uniqueid <> ( select min(y.uniqueid)
from tourn_results y
where y.tournamentid = x.tournamentid
and y.playerrank = x.playerrank );

You can add a unique index on the columns you don't want to have duplicates. It will drop all your duplicates.
ALTER IGNORE TABLE tourn_result ADD UNIQUE INDEX idx_name (tournamentId, playerRank);
The other option is to create a new temp table, insert your duplicates rows and delete them from your actual table.

In MySQL, this is most easily done with a left join:
delete tr
from tourn_results tr left join
(select tr2.tournamentid, min(uniqueid) as minui
from tourn_results tr2
where tr2.playerrank = 1
group by tr2.tournamentid
) ttr
on ttr.minui = tr.minui and ttr.tournamentid = tr.tournamentid
where tr.playerrank = 1 and ttr.minui is null;
I'm not so sure that deleting the additional "ties" for first place is the right thing to do, however.

Related

How to insert rows for each of the TYPE column?

How to insert rows for each of the type column? If there is two type, type 1 and type 2, then I need to insert two rows and also need to change the order and id value for whole table.
current status:
CHOICE Table
id choice type order
1 AA 1 1
2 BB 1 2
3 CC 1 3
4 AAA 2 4
5 BBB 2 5
6 CCC 2 6
7 DDD 2 7
Required updated table:
Now i wan to insert choice "000" for each type. The updated table will be look like bellow. How can I achieve this?
updated CHOICE Table
id choice type order
1 000 1 1
2 AA 1 2
3 BB 1 3
4 CC 1 4
5 000 2 5
6 AAA 2 6
7 BBB 2 7
8 CCC 2 8
9 DDD 2 9
here, id and order column serialized again.
The actual table is too big, so I cannot insert by edit. Please help for this complex query. I have no clue to solve this.
Use insert . . . select to insert the rows:
insert into choice (choice, type)
select distinct '000', type
from choice;
This assumes that id is automatically assigned (and it will be different from your example).
However, it looks like you want to update the order as well. For this, I would suggest an update:
update choice c join
(select c2.*,
row_number() over (partition by choice order by (order is null) desc, order) as new_order
from choice c2
) c2
on c.id = c2.id
set c.order = c2.new_order;
As an editorial comment, order is a very bad choice for a column name because it is a SQL keyword.

How to loop through a db table in mysql and show a column once even thogh it appears on different rows

database name = db_structure
id | param_id | occupation_id | amount | active
1. 1 1 20000 1
2. 2 1 20000 1
3. 3 1 20000 1
4. 1 1 20000 1
5. 2 2 20000 1
6. 3 2 20000 1
7. 4 2 20000 1
what query will I write to loop through the table to fetch the records on each row but only show occupation_id once on a table even if it appears more than once?
SELECT tbl_salarystructure.occupationid, SUM(amount), tbl_occupation.*
FROM `tbl_salarystructure`
INNER JOIN tbl_occupation ON
tbl_salarystructure.occupationid = tbl_occupation.id
WHERE tbl_salarystructure.active = 1 ORDER BY occupationid
the result of the query is this when I use php to fetch the rows on the table
Report table
Department | Amount
1 20000
1 20000
1 20000
1 20000
2 20000
2 20000
2 20000
I want the department to show once with the total sum of the amount column using php where their occupation id is thesame
Thanks guys, I got the solution to my problem... I changed the ORDER BY in my sql to GROUP BY the column I want and it came out perfect
I think you just want GROUP BY:
SELECT o.*, SUM(amount)
FROM tbl_occupation o JOIN
tbl_salarystructure ss
ON ss.occupationid = o.id
WHERE ss.active = 1
GROUP BY o.occupationid;
In general, you don't want to use SELECT * with GROUP BY. The one exception is when the primary key for the table (or any unique key actually) is one of the GROUP BY keys.

Generating SQL query with given number of rows in a query

I need to turn my table to this given output table using the column order table.
Is this even possible using SQL only?
I looked up the answer on the internet and I've seen people generally use PIVOT. However, my table has as many columns as there are rows in the column order row. So is this possible?
Any ideas/hints on how to do this are greatly appreciated.
Table I already have (yes, it's sorted by A)
A B C
---------- ---------- ----------------------
1 1 74
1 2 95
2 1 78
2 2 10
2 3 33
Order of Columns (another table I have)
B
-----
2
1
3
Wanted table (sorted by A)
A COLUMN 2 COLUMN 1 COLUMN 3
--------------------------------
1 95 74 0
2 10 78 33
As others pointed out, you need a column in the Order of Columns table representing the order. Assume that column is id, then you can use query:
select t.A,
ifnull(max(if (o.id=1, t.c, null)),0),
ifnull(max(if (o.id=2, t.c, null)),0),
ifnull(max(if (o.id=3, t.c, null)),0)
from t
join t_order o on o.b=t.b
group by t.A
See db-fiddle

Mysql select statement contains where clause so unsuitable for insert into

I'm very inexperienced. I've prepared a select statement which gives the information I need to populate a matches table. However it is not suitable because it contains a where clause. Is there a different way to use it, or how can I change it so that it is suitable for INSERT INTO.
The tables are as follows:-
match_order
match_order_id||match_descrip||first_player||second_player
1 1v2 1 2
2 1v3 1 3
3 2v3 2 3
4 1v4 1 4
5 2v4 2 4
6 3v4 3 4
entries
entry_id||round_id||league_id||box_id||box_position
1 1 1 1 1
2 1 1 1 2
3 1 1 1 3
4 1 2 1 4
5 1 2 1 2
6 1 2 1 1
7 1 2 1 1
matches
match_id||round_id||league_id||box_id||match_order_id||player1||player2
I need to insert new rows every month for a new round of matches. League size, box size & positions change each month.
This is the statement which gives the correct rows.
SELECT e.round_id, e.league_id, e.box_id, mo.match_order_id, e.entry_id as player1, e1.entry_id as player2
FROM match_order mo
LEFT JOIN entries e ON mo.first_player = e.box_position
LEFT JOIN entries e1 ON mo.second_player = e1.box_position
WHERE e.round_id = e1.round_id AND e.league_id = e1.league_id AND e.box_id = e1.box_id
ORDER BY round_id, league_id, box_id, match_order_id
Any help & advise would be greatly appreciated.
Thank you
Assuming match_id is an auto-increment column, you have the data for the other columns. You can just add the INSERT statement before your SELECT.
INSERT INTO matches(round_id, leage_id, box_id, match_order_id, player1, player2)
SELECT e.round_id, e.league_id, e.box_id, mo.match_order_id, e.entry_id as player1, e1.entry_id as player2
FROM match_order mo
LEFT JOIN entries e ON mo.first_player = e.box_position
LEFT JOIN entries e1 ON mo.second_player = e1.box_position
WHERE e.round_id = e1.round_id AND e.league_id = e1.league_id AND e.box_id = e1.box_id

How to join two tables with one similar column into one table

I have 3 tables, A and B and C.
sample data for Table A
nid tid
101 3
101 4
101 7
103 3
103 5
104 2
104 4
104 7
sample data for Table B
tid name
2 ram
3 shyam
4 krishna
5 shiv
7 narad
What I want is, in a Third Table C
id nid labels
1 101 shyam, krishna, narad
2 103 shyam, shiv
3 104 ram, krishna, narad
I know how to do this with PHP, but is there any way to do this mysql alone?
Both tables (A and B) have thousands of records and don't have any unique column at the moment.
I tried GROUP_CONCAT but I could not construct desired output.
Edit 1 - I forgot to mention that Table C already has id and nid column inserted, while labels column is empty. So I need help in constructing some query which can update all records of Table C with labels mentioned as above.
Thanks. Regards,
This will insert the records on TableC. Since ID is an autogenerated column, you can omit this in the INSERT clause.
INSERT INTO TableC(Nid, Labels)
SELECT a.nid, GROUP_CONCAT(b.Name) Labels
FROM TableA a
INNER JOIN TableB b
ON a.tid = b.tid
GROUP BY a.nid