Delete multiple rows from multiple tables in mysql using single value - php

I have a number of mysql tables with different table structures and all they have the followings table names and fieldnames (the ones of the left are table names and on the right are field names)
I want to be able to delete the values of the rows using a single variable (example $id = somename) in a single query
user id,
user_image user
user_interest user
user_lang id
user_login user
user_personal user
user_prefer user
user_reviewuser
user_role user_id
user_translang user
user_translate user
user_web id
Also, a particular userid may not be present across all tables.
I am not sure at all on how to delete them all at once. Any tips would be appreciated, i looked at a couploe of similar questions but couldn't find a proper answer.

You want to create a foreign key constraint, and specify "ON DELETE CASCADE". You'll need this for each of your tables that has a foreign key to user. For example,
ALTER TABLE user_image
ADD CONSTRAINT fk_user_image_user FOREIGN KEY (user)
REFERENCES user(id)
ON DELETE CASCADE;

You can use the multi-table DELETE syntax. You need to use a LEFT JOIN in case any of the related tables do not have a corresponding row.
DELETE user, user_image, user_interest, ...
FROM user
LEFT JOIN user_image ON user.id = user_image.user
LEFT JOIN user_interest ON user.id = user_interest.user
...
WHERE user.id = $id
DEMO
However, if you relate the tables using a foreign key constraint, with ON DELETE CASCADE, you can just delete the row from the user table, and all the related rows will be deleted.

Related

When I delete from the students table, it will also delete the items on voters table

I am new and don't know how to code well, but I want to modify the system.
TARGET: When I delete the 'id' from the students table it will also delete 'userid' from the voters table.
SCREENSHOT OF DB:
students TABLE
voters TABLE
HERE IS CODE I AM USING. (THIS CODE ONLY DELETE THE ROWS ON students TABLE)
I have tried using another query but nothing happened. Can someone please fix the code for me? I am new to this.
<?php ob_start();
session_start();
if (!isset($_SESSION['id'])){
header("location:../login.php");
}
?>
<?php
include('../connect.php');
$id=$_GET['id'];
$del = mysqli_query($connection,"DELETE FROM students WHERE id='$id'");
?>
This is a desired functionality when you are using any RDBMS. i.e. when there are 2 tables with a foreign key relationship between them and the foreign key of the 1st table is a Primary key of the 2nd table. Then deleting the 1st tables record will be triggering the deletion of the record associated with it in the 2nd table.
This is called a cascade delete which is much better explained with the below definition.
A foreign key with cascade delete means that if a record in the parent table is deleted, then the corresponding records in the child table will automatically be deleted. This is called a cascade delete in SQL Server.
MySQL:
You can delete with a JOIN like this:
DELETE users
FROM users
INNER JOIN voters
ON users.id = voters.userid
WHERE users.name = 'Jordan Santos';
See this SQL fiddle for an example with data. (You can comment out the DELETE statement with a # to see the query results without deleting anything.)
Postgres:
You could use two Common Table Expressions (i.e., WITH clauses) to do the deletions in each table:
WITH user_deletion AS (
-- this deletes the user based on username
DELETE
FROM users u
WHERE username='Dad'
RETURNING id, username
),
vote_deletion AS (
-- this gets the deleted user_id from above and deletes the corresponding vote(s)
DELETE
FROM votes
WHERE user_id = (SELECT id FROM user_deletion)
RETURNING vote_id, user_id, vote
)
-- this runs the DELETE statements in the clauses above
SELECT udel.*, vdel.*
FROM user_deletion udel
INNER JOIN vote_deletion vdel
ON udel.id = vdel.user_id;
See this SQL Fiddle for a Postgres example with data, showing results both before and after the deletion.

PDO deleting records from multiple tables using joins

i want to delete a table row with a photo table. there is also a table called photo_translate where i store my alt text in different languages. is this possible using joins?
$query=$db->prepare("DELETE FROM photo,photo_tranlate INNER JOIN photo_translate on photo.id=photo_translate.rec_id WHERE photo.rec_id=? and photo.page=?" );
$query->bindvalue(1,$rec_id);
$query->bindvalue(2,$page_id);
$query->execute();
You should set a foreign key with "on delete cascade" on the field photo_translate.rec_id
This way when you delte the record in the "photo" table, the corrisponding record in the "photo_translate" table will be deleted automatically.
This is the correct way to handle this situation

Can this mySQL query be optimized better? Not a mySQL guru but I think I got it right

Basically, I have two tables that have a 1 to 1 relation.
When I delete a row from subset_panel_options I also want to delete the related row in subset_panel_options_list
Here is some of structure for the two tables. There is no need to show the full table.
[subset_panel_options]
->id
->subset_panel_id
[subset_panel_options_list]
->id
->subset_panel_options_id
DELETE subset_panel_options, subset_panel_options_list
FROM subset_panel_options
JOIN subset_panel_options_list
WHERE subset_panel_options.id = subset_panel_options_list.subset_panel_options_id
AND subset_panel_id = $subsetPanelId
Yes, it can:
DELETE FROM subset_panel_options
LEFT JOIN subset_panel_options_list
ON (subset_panel_options.id = subset_panel_options_list.subset_panel_options_id)
WHERE subset_panel_options.subset_panel_id = $subsetPanelId
Using LEFT JOIN you ensure you are deleting from "subset_panel_options" even if there is no corresponding match in the subset_panel_options_list table.
You may also want use referential integrity features available in InnoDB engine. In this case, you need to define subset_panel_options_id as a FK (foreign key) in the subset_panel_options_list table, and an "ON DELETE CASCADE" constraint on it, meaning that when rows at subset_panel_options are deleted, the "orphan" rows in subset_panel_options_list should be immediately deleted too.

System for keeping track of user favorites

On my website, I have a table movies and a table users
I'm trying to have an "Add to favs" button that a user can click, which will add that movie to his favorites (ajax / javascript not necessary at the moment, just php).
So what's the simplest way I could do something like that? I've thought about this but I can't seem to find a solution (all I think of is way too complicated, and in my opinion not possible).
What's your thoughts?
I don't need a ready-made script, just an idea that could get me working (although if you have an example of such script, I'd be happy to look at it).
Thanks!
This is a many-to-many relationship. A user can favorite many movies, and a movie can be favored by many users. In an RDBMS, you represent a many-to-many relationship with a third table. I call this an intersection table but it goes by other names too.
Create a table with two columns. The columns are both foreign keys, referencing movies and users, respectively.
CREATE TABLE Favorites (
user_id INT NOT NULL,
movie_id INT NOT NULL,
PRIMARY KEY (user_id, movie_id),
FOREIGN KEY (user_id) REFERENCES Users(user_id),
FOREIGN KEY (movie_id) REFERENCES Movies(movie_id)
);
When a user chooses to favorite a movie:
INSERT INTO Favorites (user_id, movie_id) VALUES (?, ?)
When a user decides they don't like a movie any longer, delete the corresponding row:
DELETE FROM Favorites WHERE (user_id, movie_id) = (?, ?)
To get the set of movies favored by a given user:
SELECT movie_id FROM Favorites WHERE user_id = ?
To get the set of users who favor a given movie:
SELECT user_id FROM Favorites WHERE movie_id = ?
Regarding one of your comments:
You shouldn't make the "Add to favorite" a link. Indexers like Google will follow links, and then before you know it, every user has favorited every movie.
The general best practice is that read-only operations can be GET requests, while operations that write to the database can be POST requests. This means that you need to use a <form> element to submit POST requests, not an <a href="..."> element.
Add a third table:
CREATE TABLE user_favorites (
user_id INT NOT NULL,
movie_id INT NOT NULL,
PRIMARY KEY (user_id, movie_id),
FOREIGN KEY user_id REFERENCES users (user_id),
FOREIGN KEY movie_id REFERENCES movies (movie_id)
)
This is called an intersection table or join table, as it joins rows in the users table to rows in the movies table (as you see, each column is a foreign key). It is also defines a many-to-many relationship, because one user can like many movies and one movie can be liked by many users.
When you go to add a favorite movie for a user, all you have to do is insert a row in this table with the ID of the user and the ID of the movie:
INSERT INTO user_favorites(user_id, movie_id) VALUES([user ID], [movie ID])
To see what movies a user has favorited:
SELECT movie_id FROM user_favorites WHERE user_id = [user ID]
You will need to create a new table:
user_favorite_movies
--------------------
ID (primary key)
userID (foreign key)
movieID (foreign key)
date
Then when the user clicks the 'Add Favorite' button, you just insert a new row into user_favorite_movies with the users ID from the user table, the movie id from the movie table, and the date it was added (good for sorting later).
Hope this helps!
Best,
-Eric
You could create a table favourites with three columns, id, mid and uid. To add a favourite:
INSERT INTO favourites (mid, uid) VALUES (3, 5)
To search for favourites of one user:
SELECT * FROM favourites WHERE uid = 7
To search for people who favourited one movie:
SELECT * FROM favourites WHERE mid = 9
So far as I can see, you'll still need to use JavaScript or Ajax to do the post, unless you want to refresh the page every time thet mark/unmark a favorite, and also to add/remove the new favorite indicator in place at the same time.
Or am I missing something?

I can't delete records from MySql

I have two tables. table a references table b I believe.
When I try to delete the package alltogether like this:
$query="DELETE a, b FROM classified as a, $sql_table as b WHERE a.ad_id = '$id'
AND a.classified_id = b.classified_id AND a.poster_password='$pass'";
b MUST be deleted first I guess.
Even in PhpMyAdmin I cant delete a if b is still there, so I delete b first.
But what decides the order in which comes first?
The tables are alla InnoDB.
What should I do?
Thanks
The MySQL manual says about multi-table DELETE and foreign keys:
If you use a multiple-table DELETE
statement involving InnoDB tables for
which there are foreign key
constraints, the MySQL optimizer might
process tables in an order that
differs from that of their
parent/child relationship. In this
case, the statement fails and rolls
back. Instead, you should delete from
a single table and rely on the ON
DELETE capabilities that InnoDB
provides to cause the other tables to
be modified accordingly.
So that when a record in your main table is deleted, so are its foreign references, e.g:
ALTER TABLE products
ADD CONSTRAINT fk_supplier
FOREIGN KEY (supplier_id, supplier_name)
REFERENCES supplier(supplier_id, supplier_name)
ON DELETE CASCADE;
Your Delete syntax is invalid. You need to do this in two statements (unless as nuqqsa mentioned, you have CASCADE DELETE enabled on the relationship between table a and table b):
Delete From b
Where Exists (
Select 1
From a
Where a.poster_password = '$pass'
And a.ad_id = '$id'
And a.classified_id = b.classified_id
)
Delete From a
Where a.poster_password = '$pass'
And a.ad_id = '$id'
What decides which comes first is the foreign keys relationships. Whichever table is the parent table must be deleted from last.

Categories