I have two tables: one contains user logins and the other contains user data. I would like to delete users who may or may not exist in the latter table but definitely exist in the former. How do I account for users who may or may not exist? Please note that it should be in one query....I have tried:
DELETE houses,houseusers FROM houses INNER JOIN houseusers ON houseusers.username = houses.username WHERE houses.username='user1' OR houseusers.username='user1';
START TRANSACTION;
DELETE FROM houses WHERE username='user1';
DELETE FROM houseusers WHERE username='user1';
COMMIT;
Related
I have a products table, a category table and a join-table to link the two, named prod_cat_join. I am attempting to periodically delete all categories not associated with a product with a specific team ID. Let it be known that category has a trigger that deletes all joins in prod_cat_join associated with a category after a category is deleted. Is there a single SQL query that can be invoked to delete all categories not associated with a product and is associated with a specific team ID without running into a function/trigger error?
The trigger goes as follows:
CREATE DEFINER=`dbe1`#`%` TRIGGER `db`.`category_AFTER_DELETE` AFTER DELETE ON `category` FOR EACH ROW
BEGIN
delete from prod_cat_join where prod_cat_join.categoryID = ID;
END
And my query that is periodically called to delete all categories not associated with a product is:
DELETE db.category FROM db.category
LEFT JOIN db.prod_cat_join AS join_cat
ON join_cat.categoryID = db.category.ID
WHERE join_cat.productID IS NULL AND db.category.teamID = '1234'
I know it's possible to query all categories not associated with a product then delete the returned set of unassociated categories. But that seems inefficient as it requires two queries. Given our current setup is it possible to bypass the trigger to run the aforementioned query? Or is there some other single query method to delete the unassociated categories? And would putting an after delete trigger in prod_cat_join to delete all categories who no longer have an association to a join be effective? Would that not end up invoking the above-mentioned deletion trigger?
Guidance would be appreciated, thank you.
I have two tables one called users and another called profiles. Each of these tables has a column named user_id. What I want to do is when I insert a new user into the users table, I want to automatically copy over their new user_id in the users table to the profiles table. I don't want to use the UPDATE clause because then I would have to call that every time I add a new user. I thought that relations would achieve what I am trying to do so I made the user_id from profiles reference the user_id from users and it still doesn't update automatically. What should I do? And what is the point of relations in the first place if they don't update your columns automatically?
This is probably a design error. If rows in these two tables always exist with the same IDs, they should probably be a single table.
The foreign key you've created only guarantees that every row that exists in profiles must have the same ID as a row in users. It does not cause those rows to be created -- it just means that if you try to create a row with an ID that doesn't match, the database will throw an error.
That all being said, it's possible to create a trigger to do what you're describing:
CREATE TRIGGER user_insert_creates_profile
AFTER INSERT ON users
FOR EACH ROW
INSERT INTO profile (user_id) VALUES (NEW.user_id);
But it's probably better to reconsider your design, or to do the insert in your application. Triggers are best avoided.
I'm sure that this is a very basic question but, I at a loss and recently starting with MySQL. I have modified, created databases, users, tables, added and modified entries to the table but now I think I need to use a Join here, but I'm not sure.
In the same db I have two tables. The tasks table has two columns of interest user and keyid. While the activities table has one column of interest which is task. What I need to do is delete all tasks in the table tasks for a certain user. However, this also means I need to delete all activities for those tasks. Now the way these are related, is that the keyid value in the tasks table is the value in the task column in the activities table.
My question is how do I write the DROP or DROP + JOIN query to do this?
You could use JOIN on this one like:
DELETE Tasks, Activities
FROM Tasks INNER JOIN Activities
ON Tasks.KeyID = Activities.Task
WHERE Tasks.User = 'User Name Here'
But it would have been better if you use ON DELETE CASCADE when you designed the table so that you will have to delete from the mother table and all the related records of the child table would also be deleted automatically.
See example here.
You could do it in 2 separate queries?
DELETE FROM activities WHERE task IN
( SELECT keyid FROM tasks WHERE user = 'CertainUser') ;
DELETE FROM tasks WHERE user = 'CertainUser' ;
Sorry for the ambiguous title.
I have two tables:
table 1: mailing_email
table 2 (dynamic table but for now is): membership
table 1 contains a list of all email accounts in the database and few ancillary fields such as name. It also has a column called communicate.
communicate is basically my terminology for subscribed. Any unsubscribe link will set communicate to false.
Both mailing_email and membership have a email and communicate column.
I need to write a query where the following happens:
mailing_email.communicate gets updated to the current status of membership.communicate where mailing_email.email = membership.email. If an email exists in mailing_email which does not exist in membership, the communicate field stays the same.
How would i go about doing this the fastest possible way? Each table will have thousands of rows this sync command would run often.
MySQL offers an update join syntax:
UPDATE mailing_email
JOIN membership ON mailing_email.email = membership.email
SET mailing_email.communicate = membership.communicate
I've read some of Bill Karwin's answers about single table inheritance and think this approach would be good for the setup I am considering:
Playlist
--------
id AUTO_INCREMENT
title
TeamPlaylist
------------
id REFERENCES Playlist.id
teamId REFERENCES Team.id
UserPlaylist
------------
id REFERENCES Playlist.id
userId REFERENCES User.id
PlaylistVideo
-------------
id
playlistId REFERENCES Playlist.id
videoId REFERENCES Video.id
All the CASCADE options are set to DELETE which will work correctly for when a Playlist is deleted, however, what happens if a User or Team is deleted?
ie. If a User is deleted, the rows in UserPlaylist will be deleted but the referenced rows in Playlist and PlaylistVideo will remain. I thought about enforcing this as a TRIGGER AFTER DELETE but there is no way of knowing if the delete request came about because the Playlist was deleted or if the User was deleted.
What is the best way to enforce integrity in this situation?
Edit (Provided ERD)
What you can do is implement triggers on your Users and Team tables that execute whenever rows get deleted from either:
User table:
DELIMITER $$
CREATE TRIGGER user_playlist_delete
BEFORE DELETE ON User FOR EACH ROW
BEGIN
DELETE a FROM Playlist a
INNER JOIN UserPlaylist b ON a.id = b.id AND b.userId = OLD.id;
END$$
DELIMITER ;
Team table:
DELIMITER $$
CREATE TRIGGER team_playlist_delete
BEFORE DELETE ON Team FOR EACH ROW
BEGIN
DELETE a FROM Playlist a
INNER JOIN TeamPlaylist b ON a.id = b.id AND b.teamId = OLD.id;
END$$
DELIMITER ;
What these triggers will do is each time a record is deleted from one of these tables, a DELETE operation will automatically execute on the Playlists table using the id that's about to be deleted (via an inner join).
I have tested this and it works great.
OK I see what you want here... what you want to do is run a query like
DELETE FROM playlist
WHERE id
NOT IN (
SELECT id
FROM UserPlayList
UNION
SELECT id
FROM TeamPlayList
)
after either a row is deleted from either users or teams
In my view, the problem is that your User and Team tables are the ones that should have a supertype table (such as Party), not the Playlist tables.
As you've pointed out, doing your "table inheritance" on playlists comes with penalties when trying to figure out what to delete. All those problems go away when you move the inheritance up to the user/team level.
You can see this answer for more detail about supertyping/subtyping.
I'm sorry to not supply code as I don't know the MySQL syntax by heart.
The basic concept is that the supertype table allows you to implement a database kind of polymorphism. When the table you're working with needs to link to any one of a group of subtypes, you just make the FK point to the supertype instead, and this automatically gets you the desired "only a one of these at a time" business constraint. The super type has a "one-to-zero-or-one" relationship with each of the subtype tables, and each subtype table uses the same value in its PK as the PK from the supertype table.
In your database, by having just one Playlist table with an FK to Party (PartyID), you have easily enforced your business rule at the database level without triggers.
The answer by Zane Bien is quite obvious & superb.But I have an idea for doing this without use of trigger because trigger has many problems.
Are you using any programming language ? If yes then,
Use a single transaction and make your database auto commit false
write a delete query for the referenced rows in Playlist and PlaylistVideo . Manually you have to write this query first by using that reference id(with where condition) and run it.
Now prepare another query for your main task i.e. delete the User, and the rows in UserPlaylist will be deleted automatically ( due to CASCADE DELETE option).Now run your second query and commit.
Finally make your transaction auto commit true.
It is working successfully, hope it will helpful.