Delete multiple rows of data from multiple tables in SQL - sql

I need help of making a SQL query, when I delete the main category it should delete all the data of my subcategory and all the products related to that subcategory. Basically deleting data from 3 tables.
Can it be done in one query?

Cant give you code sample without a Database reference. But if all the tables have the same Primary key you can try using INNER JOIN.
DELETE table1, table2, table3
FROM table1
INNER JOIN table2 ON table2.key = table1.key
INNER JOIN table3 ON table3.key = table1.key
WHERE table1.key = value;
key value should be common accross all tables. Something like a "ID".

Instead of solving it via Sql, you could use foreign keys with the ON DELETE CASCADE setting enabled.
If you database type/version supports it.
F.e. ANSI SQL:2003, MySSQL, Oracle, PostgreSQL, MS SQL Server, SQLite
That way, when you delete from the main table. Then the records in the other table that reference to those deleted records, will automatically be deleted also.
For example in MS Sql Server:
ALTER TABLE SubCategory
ADD CONSTRAINT FK_SubCategory_MainCategoryID_Cascade
FOREIGN KEY (MainCategoryID)
REFERENCES MainCategory(ID) ON DELETE CASCADE;
ALTER TABLE Products
ADD CONSTRAINT FK_Products_SubCategoryID_Cascade
FOREIGN KEY (SubCategoryID)
REFERENCES SubCategory(ID) ON DELETE CASCADE;
It's a way to automatically maintain the referential integrity between them.
After that a delete from the MainCategory table will delete the related records from the SubCategory table. And also the Products that are related to the deleted SubCategory records.
And here is a db<>fiddle example for SQLite to demonstrate.
P.S. Personally I would prefere an ON DELETE SET NULL or an ON DELETE SET DEFAULT n, or even using triggers. Sure, that would require an extra cleanup of the unreferenced records afterwards, f.e. via a scheduled script. But it just feels less detrimental. Because then it's easier to fix when someone accidently deleted a MainCategory that shouldn't have been deleted.

Related

Deleting rows from multiple tables

I created a query that will delete rows from three tables that has 'Employee'.
When I execute it, it only deletes rows from one table tblEmployeeType. I tried adding Alias of other tables beside DELETE but SQL does not support it. Is there any alternative way of deleting rows from multiple tables? or I forgot some codes on my query or should I just separate delete queries? Thank you.
DELETE a
FROM tblEmployeeType a INNER JOIN
tbl_Selected_AccessType b
ON a.EmpTypeName = b.UserType INNER JOIN
tbl_AccessType_AllFunction c
ON a.EmpTypeName = c.UserType
WHERE a.EmpTypeName = 'Employee'`
INSERT and UPDATE statements can only directly affect one table at a time. If you have foreign keys configured with ON DELETE CASCADE then child records will be deleted along with the parent record. Regardless of using cascade, you should have foreign keys on the table so that your DELETE doesn't leave orphaned child records with broken referential integrity.
Another way to achieve affecting other tables in an INSERT or UPDATE is by using a trigger on the table. This can be desirable when you want to do checks before blindly deleting child records.

Delete from 2 tables using INNER JOIN

I have 3 tables.
InvoiceOriginal
Invoice
InvoiceHistory
the invoice table has a foreign key constraint.
Each entry in the invoice table has a corresponding entry in Invoiceoriginal.
The invoiceOriginal table stores the original values of the invoice and invoice table stores the values which have been modified by the user.
this is done to get diferrences at the time of submission.
the SQL I am using is
DELETE i
FROM invoice i
INNER JOIN InvoiceHistory aih
ON i.ClientId = aih.HistoryClientNumber
AND i.invoiceNumber = HistoryInvoiceNumber
however deletion is not possible because of foreign Key constraint.
The table is as under:
Invoice InvoiceOriginal InvoiceHistory
Id FK_InvoiceId ClientId
ClientId ClientId InvoiceNumber
InvoiceNumber
I need to delete the entry in invoice and InvoiceOriginal once there is an entry for that invoice number in InvoiceHistory for the same clientId.
You cannot issue a delete statement against more than one table at a time, you need to have individual delete statements for each of the related tables before deleting the parent record(s)
I'm fairly sure you can't delete from multiple tables with a single statement. I would normally delete the child rows first with one statement and then delete the parent record. You may wish to do this inside a transaction if you might need to roll back on failure.
Alternatively, you could enable CASCADE ON DELETE on the foreign key which would automatically cascade the deletions through the child records if that is something that is suitable for this system.
You can't delete the records from multiple table from a single query. But you have two methods to solve this
Delete all the related records from child or mapping table, and then
delete the Parent / header table record. (Multiple queries required here. Use SQL Transaction for a better control).
Or, Modify your foreign key constraint to ON DELETE CASCADE
Yes, YOU CAN, I did it right now:
DELETE T1,T2 FROM T1
INNER JOIN
T2 ON T2.FIELD = T1.FIELD
WHERE
T1.SOMETHING='SOMETHING'

Deleting a Row in Table- Best way to also delete all rows it affects?

I have created a very simple SQL script (see below) that deletes rows in my table if a column name is a certain value.
DELETE FROM table_name
WHERE some_column=some_value;
However, this table also enters data to other tables in my Database: For example it's ID (Primary Key).
How can I also delete the rows in the other tables?
I would recommend a stored procedure in the database to do your delete. Not only can you do the delete in the proper constraint order but you have the added benefit of not having to grant delete permission on the table - only execute permission on the proc.
Like said #Gordon,
Add a foreign key to your table_name and ask for cascade_on_delete
or
DELETE table1, table2 FROM table1 INNER JOIN table2 ON table1.column=table2.column AND table1.column = someValue
...Not sure about the correct synthax but that will work.

Delete rows from multiple tables in a database

I want to delete some records from a table based on criteria in another table. How do you delete from one of those tables without removing the records in both table?
I am looking to delete a table which are joined with other tables and the query looks something like this.
DELETE DeletingFromTable
FROM DeletingFromTable
INNER JOIN CriteriaTable ON DeletingFromTable.field_id = CriteriaTable.id
WHERE CriteriaTable.criteria = "value" ;
This should work:
DELETE DeleteFromTable FROM DeleteFromTable AS DT
JOIN CriteriaFromTable AS CT ON DT.SomeId = CT.SomeId
WHERE CT.SomeId=[value]
Your question is not 100% clear on what your issue is, but this query will drop tables 1,2 and 3 at the same time:
DROP TABLE table1,table2,table3
You can only delete data from one table at a time.
To delete from multiple table
Write multiple queries separated by semicolon and execute it at onces like
delete from table1;
delete from table2;
delete from table3;
Or you can write the procedure to do this task.
Please check this thread as well
Drop multiple tables in one shot in mysql
You can use:
DELETE FROM TableName
Which will remove all the data, but if you have any seeded columns, these will not be reset. If you want to DELETE data and reset the seeding of PK's, then use TRUNCATE...
TRUNCATE TABLE TableName
But, you need to consider whether you have other tables that have referential integrity, if this is the case, see this post here SQL Server: How to ignore referential integrity until COMMIT?
EDIT:
Your comment above...
delete query like this DELETE FROM table_name WHERE
some_column=some_value;
...suggests you are looking to delete specific rows?
You can just write a query to DROP the tables like so:
DROP TABLE [TABLE_1]
DROP TABLE [TABLE_2]
DROP TABLE [TABLE_3]
Depending on the tables and any constraints you may have between them, you will need to DROP the tables in the correct order.
If you right click any table (depending on SQL version), you should be able to 'View Dependencies'. If the 3 tables you are planning to DROP are only dependant on each other, you need to DROP the tables with no child dependencies first to avoid it failing.
For example, if you try to delete a parent table where it's primary key is referenced in a child table as a foreign key, the DROP will fail because of this. So deleting the child table with the foreign key first will allow you to subsequently DROP the parent table.
If however, the tables have other dependencies outside the tables you are deleting, you will need to remove the dependencies before this will work.

PostgreSQL: List dependent rows

How can I see which entries depend on a given entry using PostgreSQL ? (dependent meaning "having a foreign key referencing the entry").
Basically, I want to check which entries might be cascaded when I DELETE a given entry of a table.
To see all actual rows depending via fk constraint, identify the columns with the tools described below.
Where foreign key constraints are defined with ON DELETE CASCADE, depending rows will be deleted (possibly cascading the DELETE to more depending tables).
Where foreign key constraints are defined with ON DELETE SET NULL / ON DELETE SET DEFAULT, only the value in the columns will be reset to NULL / default value.
Else a DELETE on rows with dependent rows would fail with an exception.
Then run queries like the following on the identified tables / columns:
SELECT f.tbl_fk_id, f.col_fk
FROM tbl_fk f
JOIN tbl t ON f.col_fk = t.col
AND <same condition as DELETE here>;
pgAdmin supplies this feature:
Pick the the object in the object browser to the left and chose the dependents pane top right.
pgAdmin uses a couple of queries to the system catalog to assemble the list. You could log the commands issued if you want to build a query yourself.
Also, when deleting an object where you are not completely sure about dependents, try a plain DROP first (without CASCADE). You will get an error message if any dependent exists ...
And finally, but proceed with caution!, you can start a transaction and just issue the command:
BEGIN;
DROP TABLE tbl CASCADE;
Then, if you like what you see:
COMMIT;
If you don't:
ROLLBACK;
And it will be like it never happened. ;)
You will see something like this:
NOTICE: drop cascades to 4 other objects
DETAIL: drop cascades to constraint tbl1_tbl_id_fkey on table myschema.tbl1
drop cascades to constraint tbl_winner_tbl_id_fkey on table myschema.tbl_foo
drop cascades to constraint bar_tbl_id_fkey on table myschema.bar
drop cascades to constraint tbl1_tbl_id_fkey on table x.tbl1
Query returned successfully with no result in 47 ms.
You can query this directly from the PostgreSQL system catalog:
SELECT
depending.relname as depending_table,
referenced.relname as referenced_table
FROM pg_catalog.pg_depend d
JOIN pg_catalog.pg_constraint fkey ON fkey.oid=d.objid AND fkey.contype='f'
JOIN pg_catalog.pg_class depending ON depending.oid=fkey.conrelid
JOIN pg_catalog.pg_class referenced ON referenced.oid=d.refobjid
WHERE fkey.confdeltype='c' -- just cascading deletes
AND referenced.oid != depending.oid -- ignoring reflexive dependencies
AND referenced.relkind='r' -- tables only
See this SQL Fiddle and the relevant documentation:
pg_depend for learning about dependencies
pg_constraint for learning about foreign keys
pg_class for learning about tables
Extending this to tell you the columns involved is left as an exercise for the reader. (Hint: pg_attribute.)
The existing answers use pg_catalog, which is OK but can incompatibly change between major versions of PostgreSQL. Wherever possible you should use the information_schema instead.
SELECT *
FROM information_schema.constraint_column_usage ccu
INNER JOIN information_schema.referential_constraints rc
USING (constraint_catalog, constraint_schema, constraint_name);
See:
referential_constraints
constraint_column_usage
constraint_table_usage