MySQL: delete duplicate rows, keep none - mysql

newbie here, for this table I would like to remove all ID's (rows) that don't have a unique number in Event. So far I found only solutions that will keep one ID, but remove the duplicates.
+-----------+--------------+----------+--------+
| ID | Costs | Date | Event |
+-----------+--------------+----------+--------+
| 1 | 100 |2012/09/10| 5 |
+-----------+--------------+----------+--------+
| 2 | 300 |2012/09/20| 5 |
+-----------+--------------+----------+--------+
| 3 | 400 |2012/10/01| 4 |
+-----------+--------------+----------+--------+
I have tried the ALTER IGNORE TABLE ADD UNIQUE INDEX function, but i don't want to keep one ID. For example, in this table I would like to remove the rows from ID 1 and 2, but keep ID 3.
Note: all ID's are unique.
Thank you.

you can use HAVING to get Event that has duplicate value, then use it in DELETE query instead of using the ID in WHERE criteria, isn't it?

Related

How to optimize an update query for multiple rows using MySQL and PHP

I have a table that has around 80.000 records. It has 4 columns:
| id | code | size | qty |
+--------+--------+-------+------+
| 1 | 4735 | M | 5 |
| 2 | 8452 | L | 2 |
...
| 81456 | 9145 | XS | 13 |
The code column is unique.
I have to update the qty twice a day.
For that i'm using this query:
UPDATE stock SET qty = CASE id
WHEN 1 THEN 10
WHEN 2 THEN 8
...
WHEN 2500 THEN 20
END
WHERE id IN (1,2,...,2500);
I am splitting the query to update 2500 stocks at a time using PHP.
Here is (in seconds) how much it takes for each 2500 stocks to update:
[0]7.11
[1]11.30
[2]19.86
[3]27.01
[4]36.25
[5]44.21
[6]51.44
[7]61.03
[8]71.53
[9]81.14
[10]89.12
[11]99.99
[12]111.46
[13]121.86
[14]131.19
[15]136.94
[END]137
As you can see it takes between 5 - 9 seconds to update 2500 products which i think is quiet a lot.
What can i change to speed things up?
Thank you!
Because the times seem to be getting longer the further along you get, I'd expect you need an index on the id field, as it looks suspiciously like it's doing a full table scan. You can create the index something like this
CREATE INDEX my_first_index ON table(id);
(I am having to add this as an answer because I can't make comments, I know it is more of a comment!!)
** EDIT **
I re-read and see your issue is bigger. I still think there is a chance that putting an index on id would fix it but a better solution would be to have a new table for the id to quantity mappings, lets call it qty_mapping
| id | qty |
+--------+------+
| 1 | 10 |
| 2 | 8 |
...
| 2500 | 20 |
make sure to index id and then you can change your update to
update stock set qty = (select qm.qty from qty_mapping qm where qm.id = stock.id)
It should be able to update the whole 80,000 records in next to no time.

how to use where caluse on primary key? [duplicate]

This question already has an answer here:
Query Distinct values from a multi-valued column
(1 answer)
Closed 5 years ago.
i'm developing a quiz website. In my database, I need a table which shows
reported quiz errors. It should look like this:
______________________________________________________________________
|key| quiz_number | who_reported_this_error | reported_number |
-----------------------------------------------------------------------
| 1 | 5 | goid482,saiai10,hahakaka | 3 |
-----------------------------------------------------------------------
| 2 | 3 | fiiai55,kihogi84 | 1 |
-----------------------------------------------------------------------
If a user named hanabi reported an error about quiz number 5,
first I need to check the who_reported_this_error column because
I don't want for a user to report same error twice. If the user 'hanabi' doesn't exist in "who_reported_this_error" column I should update row 1.
Now for my problem. I want to find a row which I should update with a key column, and the key column's number should automatically increased. But I know that I can't use a WHERE clause on this primary key. Hhow can I solve this problem?
The problem is with the table schema. NEVER store comma-separated data in a single column. You should structure the table to look more like this:
____________________________________________
|key| quiz_number | who_reported_this_error |
────────────────────────────────────────────
| 1 | 5 | goid482 |
---------------------------------------------
| 2 | 3 | fiiai55 |
---------------------------------------------
| 3 | 5 | saiai10 |
---------------------------------------------
| 4 | 5 | hahakaka |
---------------------------------------------
| 5 | 3 | kihogi84 |
--------------------------------------------
You might also want a timestamp column on this table. Then, put a UNIQUE constraint on the quiz_number and who_reported_this_error columns to prevent the duplicates.
If you later need to see everyone who reported errors for quiz 5 in the same record, use MySql's group_concat() function to build that information on the fly. Just don't store the data that way.
The key column has nothing to do with this question. You certainly can use your primary key in a WHERE clause. It just won't help you in this case because that data isn't relevant to the problem at hand.

How to delete half the records of a table?

I have this table that holds user relations of a social network website with the following structure.
+--------+----------------+
| user_id| friend_user_id |
+--------+----------------+
And there is 2 record for every individual relationship in the table. Something like the following:
+--------+----------------+
| user_id| friend_user_id |
+--------+----------------+
| 1 | 2 |
| 2 | 1 |
| 4 | 7 |
| 8 | 15 |
| 7 | 4 |
| 15 | 8 |
+--------+----------------+
Now what I need to do is for every single relationship to be only one record present. Meaning I need to delete every second record of every relationship.
I have tried various queries to no avail. If anyone could come up with the suitable query I'll be truly grateful.
It looks like the relationships exist in pairs. So user A has user B as a friend and user B has user A as a friend. If I read your question right, you want to remove one of the relationships but leave the other.
Since they have different user_ids, you could delete all the rows where user_id is greater than friend_user_id. That would delete one of the relationships but keep the other.
delete table where user_id > friend_user_id

How to select multiple entries with the same value in one column in T-SQL

So, I am working in Visual Studio 2013. And I have a table like this:
id | fk | data
----------------------
1 | 1 | something1
2 | 1 | something2
3 | 1 | something3
. | . | ...
. | . | ...
6 | 2 | ...
The fk is a foreign key to another table. I want to select all the rows which have the same fk. There is an undefined number of the same fk entries (there could be 5 rows with value 1 and 3 rows with value 2, etc.) But, I want to be able to switch said fk in my program so that when i put the DB in a Form in Visual Studio, clicking a button next would get me the next value of the fk. For example, I would like the first result to come out like this:
id | fk | data
----------------------
1 | 1 | something1
2 | 1 | something2
3 | 1 | something3
And when I click next to get me to the next entry, the result would be:
id | fk | data
----------------------
6 | 2 | ....
7 | 2 | ....
Is there a way in SQL to combine just the results with the same fk value? All of the solutions I have found so far gave me all of the fk values (all entries). I haven't found a way to get just all the entries with a single, unique value in the fk column.
You're looking for a basic SELECT statement with a WHERE clause:
SELECT
id, fk, data
FROM
your_table_name
WHERE
fk = 1
I can't help you with the VisualStudio stuff though, but you'll just have to repeat the same query incrementing the fk value in the WHERE clause

How to prevent race condition with INSERT?

How would i go about preventing race conditions when INSERTing a row into a table that contains no unique index. For example say my table is....
key | slot | label
------------------
1 | 1 | some
1 | 2 | some
2 | 1 | some
2 | 2 | some
... is the only way to prevent such race conditions to create a composite unique field such as "key:slot" e.g.
id | key | slot | label
------------------------
1:1 | 1 | 1 | some
1:2 | 1 | 2 | some
2:1 | 2 | 1 | some
2:2 | 2 | 2 | some
...or is there a more efficient way that has escaped me? What about if i was to check for duplicate rows after the insert has been performed and roll the transaction back if there are any found?
actually you can do it without the key:slot column. You can define a unique compound key on the table. eg,
ALTER TABLE tableName ADD CONTRAINT tb_uq UNIQUE (`key`, slot)
How about using LOCK TABLES syntax to prevent race conditions when inserting?