Consider we have a field named (username) in our table named (tpl_users), now this table has lots of duplicated rows
I wrote this code to delete duplicated usernames:
Delete FROM tpl_users WHERE username = username;
How is it possible to delete duplicated usernames?
Your query deletes all the rows where the user name is not NULL.
If you want to identify the user names which are associated with more than one row:
SELECT username
FROM tpl_users
GROUP BY username
HAVING COUNT(*) > 1;
Before converting that into a DELETE, you need to be aware that the majority of queries will delete all the records associated with a duplicated name, rather than retaining just one of the duplicates.
What you want to do is delete duplicate rows.
You'll do this by finding all non-duplicate rows, and replacing the table with those rows:
create table tpl_users_new as select distinct * from tpl_users;
alter table tpl_users rename to tpl_users_old;
alter table tpl_users_new rename to tpl_users;
If you want to keep the users with the lowest id, first make sure this query has what you want to remove (and backup your database):
SELECT u1.id, u1.username FROM tpl_users u1 LEFT JOIN tpl_users u2 ON u1.username = u2.username WHERE u1.id > u2.id;
Then, if your database is backed up, and you're sure the above statement represents what you want to remove.
DELETE u1 FROM tpl_users u1 LEFT JOIN tpl_users u2 ON u1.username = u2.username WHERE u1.id > u2.id
Assuming you have a primary key column in the table, you can do this:
DELETE
FROM tpl_uers
USING tpl_users, tpl_users AS vtable
WHERE vtable.id > tpl_users.id
AND tpl_users.username = vtable.username
Related
Hi I have two tables as per following.....
tbl_favorite_properties
1 favorite_properties_id
2 favorite_properties_property_id
3 favorite_properties_user_id
tbl_property
1 property_id
2 property_user_id
Now i want to delete fields based on user which is straight forward as below
$user_id = $_SESSION['user_id'];
$delete_tbl_favorite_properties = $con->prepare("DELETE FROM tbl_favorite_properties WHERE favorite_properties_user_id='$user_id'");
$delete_tbl_favorite_properties-> execute();
$delete_tbl_property = $con->prepare("DELETE FROM tbl_property WHERE property_user_id='$user_id'");
$delete_tbl_property-> execute();
Now I want to delete all properties in tbl_favorite_properties (favorite_properties_property_id) which match this users properties in tbl_property (property_id)
I am already able to do this in innodb cascade delete using mysql, but need a php solution.
there is a solution here How do I delete row with primary key using foreign key from other table?
but there the column names are the same and mine are different...
i am new to structuring queries in multiple tables...
I think the behavior you want is to remove properties in tbl_property belonging to a certain user, but then to also delete the corresponding favorites in tbl_favorite_properties:
DELETE t1, t2
FROM tbl_property t1
LEFT JOIN tbl_favorite_properties t2
ON t1.property_id = t2.favorite_properties_property_id
WHERE t1.property_user_id = '$user_id'
What threw me off initially is that both tables have a user_id column. You might not need the user_id in tbl_favorite_properties if you always plan to enter that table via a join from tbl_property.
Please, could you help me, how to delete data from more than 1 table in just one query?
I have this tables structure:
products
texts
files
products_files - here are mapped files to products - product_id, file_id
texts_files - here are mapped files to texts - text_id, file_id
And I need to do this:
If I delete file with id 50, I need to delete all rows from products_files and texts_files where file_id = 50.
Do you know, how to do it?
I tried to use left join, but without any results...
$query = 'DELETE products_files, texts_files FROM products_files
LEFT JOIN texts_files ON texts_files.file_id = products_files.file_id
WHERE products_files.file_id = '.$id.' OR texts_files.file_id = '.$id.'';
You might need ON DELETE CASCADE functionality. However, use it with care as it might have surprising consequences:
http://www.mysqltutorial.org/mysql-on-delete-cascade/
If you add ON DELETE CASCADE in your create table-query, you can delete any item from it. If there are any foreign key constraints, mysql automatically follows the connection and also deletes entries in the other table.
If you wanna stay on the safe side though (recommended), you will need to use multiple delete statements.
you can specify which table to delete from by prefixing a * with the table name: DELETE table.* FROM table1 JOIN table2 JOIN ... WHERE ... The WHERE clause specifies which rows to delete.
Try this:
DELETE f1,f2
FROM products_files f1
INNER JOIN texts_files f2 ON f1.file_id = f2.file_id
WHERE f1.file_id = '.$id.';
OR
use MySQL Foreign Key constraints
MySQL foreign key constraints, cascade delete
Essentially your query seems fine to me (except for the LEFT JOIN) - does this not work...
DELETE pf
, tf
FROM products_files pf
JOIN texts_files tf
ON tf.file_id = pf.file_id
WHERE pf.file_id = $id;
I have 3 tables. 1 table is like the master table and I want all rows from this table where GameID = X. Then I have a guides table which will have a matching ID and finally i have a user table that defines whether the user has selected this row to be hidden. this is causing issues. This table may not have a row associated with it. This table is shared amongst ALL users. The primary key of this table is UserID+InfoID. The query below returns what I want provided there are no other rows in the table for other userIDs.
SELECT PS_Info.*, PS_Guides.Guide, PS_Userhidden.* FROM PS_Info
LEFT JOIN PS_Guides ON PS_Info.ID = PS_Guides.InfoID
LEFT JOIN PS_Userhidden ON PS_Info.ID = PS_Userhidden.InfoID
WHERE PS_Info.GameID = :ID AND (PS_Userhidden.UserID = :UserID)
OR (PS_Userhidden.UserID IS NULL AND PS_Userhidden.InfoID IS NULL)
So I will run the php script and have infoID =1 and userID=1. In the table there is infoID=1 and userid = 2, but nothing will be returned for this row. If I remove PS_Userhidden.UserID = :UserID I get multiple of the same row. The user table will grow to millions of rows. I need a way to make this query stick to the primary key of the users table so it will still return a row if no match exists in the user table and also return a row if there is a match in the users table for the specific user
I think you just need to move the condition on the hidden user to the ON clause:
SELECT i.*, g.Guide, h.*
FROM PS_Info i LEFT JOIN
PS_Guides g
ON i.ID = g.InfoID LEFT JOIN
PS_Userhidden h
ON i.ID = h.InfoID AND h.UserID = :UserID
WHERE i.GameID = :ID ;
Your description of the problem sounds like something that can happen when you start fiddling with conditions in the WHERE clause of a LEFT JOIN. It is a little hard to follow though. If this doesn't work, edit your question with sample data and desired results -- or, better yet, set up a SQL Fiddle.
I have a form from where Information is entered into multiple database having same id, if by mistake wrong data is entered, I want to delete that from all tables.
How and what should I do to delete from all information related to that id from all tables.
You can do multiple table deletes:-
http://dev.mysql.com/doc/refman/5.0/en/delete.html
For example say you had 4 tables and want to delete all the records in 3 of them that relate to the 1st table:-
DELETE Table1, Table2, Table3
FROM Table0
INNER JOIN Table1
ON Table0.Id = Table1.ParentId
INNER JOIN Table2
ON Table0.Id = Table2.ParentId
INNER JOIN Table3
ON Table0.Id = Table3.ParentId
WHERE Table0.Id = 1
Of course you could also delete from the first table (Table0) as well.
I'm trying to create a list in PHP of the oldest entries for each user in the database.
SELECT *,
MIN(`entries`.`entry_date`)
AS entry_date
FROM (`entries`)
JOIN `user_profiles`
ON `user_profiles`.`user_id` = `entries`.`user_id`
WHERE `status` = 1
GROUP BY `entries`.`user_id`
I'm using the query to retrieve from the entries table the oldest dated entry using MIN()and joining with table user_profiles for other data. The query should select the oldest entry for each user. It seems to work but it retrieves the wrong entry_date field on some entries when I echo them. Please help, I can't spot what I'm doing wrong..
You need to use a subquery to obtain the (user_id, entry_date) pairs for each user, then join that with a query that selects the records of interest:
SELECT *
FROM entries
NATURAL JOIN (
SELECT user_id, MIN(entry_date) AS entry_date
FROM entries
GROUP BY user_id
) AS tmin
JOIN user_profiles USING (user_id)
WHERE status = 1
Have you tried approaching the problem from the user_profiles table instead of the entries table? If a user has no entries, they will not appear in the above query.
This may help, but I'm not sure if it's the full solution:
SELECT *, MIN(entries.entry_date) as entry_date
FROM user_profiles LEFT JOIN entries USING (user_id)
WHERE status = 1
GROUP BY user_profiles.user_id
Also, you're renaming the MIN(entires.entry_date) as entry_date... but you already have a column named entry_date. Try renaming the derived columns to something unique like "min_entry_date"?