Delete from two tables with inner join - sql

How can I delete rows from two different tables in one single query?
Part of the query is: WHERE Lendings.Id = (the id I want to delete)
The Column "ProductId" refer to the "Id" column in the Products table.
Table: Lendings
Id - ProductId
Table: Products
Id - Name
EDIT:
I do this instead :)
function DeleteLending($lendingid, $productid)
{
global $conn;
$sql = "DELETE FROM Lendings WHERE Id = ?; DELETE FROM Products WHERE Id = ?;";
$params = array($lendingid, $productid);
$stmt = sqlsrv_query($conn, $sql, $params);
}

You can't.
DELETE only deletes from one table at a time. You can, however, use the join clauses to delete in one table, depending on data in another table, but you cannot delete from two tables in one statement.
Issue two delete statements.

Related

SQL select with three tables

Hi guys I'm new with databases and I'm trying to make a query where I join 3 tables. I could make it and I want to clean up the result. I want to know how can I delete the column "pin" from users table and maybe some "ids" columns.
Select * from "wish-list"
Join products
On "wish-list".id = products.holiday_id
Join users
On "wish-list".user_id = users.id
Where "wish-list".id = 1
You need to specify which columns you really need in your output. At the moment you are using
SELECT * which outputs all columns of all joined tables.
Here is what it should look like:
SELECT holiday, products.description, users.pin FROM "wish-list"
JOIN products ON "wish-list".id = products.holiday_id
JOIN users ON "wish-list".user_id = users.id
WHERE "wish-list".id = 1
It's important that you reference all columns which are not your main entity (here wish-list) with tablename.column (products.description and not only description). It will work without referencing strictly but only if the column name is unique in your query.
Furthermore you can rename columns. This is useful for example if you want to get the id's of the product table and the wish-list table.
SELECT product.id AS product_id, id AS wishlist_id FROM "wish-list"
...
Hope that helps!

Performing a query on a foreign table but returning only the original table?

Let's say I have a Item and Person table, where the Person 'id' column matches the Item 'person_id' column. I want to retrieve records in the Item table where the owner (Person) of the Item has 'category' 1. Sample structure below:
Item
id
item_name
person_id
Person
id
name
category (can be 1, 2, or 3)
I understand that I can use 'join' to find rows of the Item table where the two ids match, but I cannot use join for my use case. I need my SQL query to return only Item columns, and not Person columns. Basically, how can I construct a query that will query a table using values in another table, while still maintaining the original table structure?
I understand that I can use 'join' to find rows of the Item table where the two ids match, but I cannot use join for my use case. I need my SQL query to return only Item columns, and not Person columns.
This statement is just false. You can select whatever columns you want when joining:
select i.*
from items i join
persons p
on i.person_id = p.id and p.category = 1;
In terms of constructing the query, exists is also a very reasonable approach, but you can definitely use join.
One way is using EXISTS with correlated subquery
SELECT *
FROM Item i
WHERE EXISTS (SELECT 1
FROM Person p
WHERE p.id = i.person_id AND p.category = 1)
You could use IN clause to filter the person table with category 1
SELECT * FROM Item WHERE person_id IN (
SELECT Id FROM Person WHERE category=1)

Overwrite values from one table to another using

I have two tables, customer and newCustomer. For specific columns, I want to overwrite the column values of customer table with the newCustomer table. For example :
customer.firstname = newCustomer.firstname
customer.lastname = newCustomer.lastname
** I do have matching Ids for the two tables.
I can think of how to do this in terms of coding, but am having a hard time when thinking of doing this in SQL.
I am using Microsoft SQL Server.
Would appreciate any examples or hints.
Presumably, you have some id that connects the two tables. If so, just use join and set:
update c
set firstname = nc.firstname,
lastname = nc.lastname
from customer c join
newcustomer nc
on c.customerid = nc.customerid;

Postgres Update multiple rows

I need to update multiple rows in a table.
i have table customer and contact
I need to update customer where the linked contact in the contact table has the column city at a certain value.
I can get the rows i need with this query
Select cus.id, con.city
from customer cus, contact con
where cus.contacts_id=con.id
and con.city="MyValue"
I know how to update one table but do not understand how to update the table when the rows are looked up from a different table.
Firstly, please do not use the old JOINs (FROM comma separated tables).
Secondly, here you go:
UPDATE customer SET whatever = 'whatever value'
WHERE contacts_id IN (
SELECT id FROM contact WHERE city="MyValue"
)

Update values in each row based on foreign_key value

Downloads table:
id (primary key)
user_id
item_id
created_at
updated_at
The user_id and item_id in this case are both incorrect, however, they're properly stored in the users and items table, respectively (import_id for in each table). Here's what I'm trying to script:
downloads.each do |download|
user = User.find_by_import_id(download.user_id)
item = item.find_by_import_id(download.item_id)
if user && item
download.update_attributes(:user_id => user.id, :item.id => item.id)
end
end
So,
look up the user and item based on
their respective "import_id"'s. Then
update those values in the download record
This takes forever with a ton of rows. Anyway to do this in SQL?
If I understand you correctly, you simply need to add two sub-querys in your SELECT statement to lookup the correct IDs. For example:
SELECT id,
(SELECT correct_id FROM User WHERE import_id=user_id) AS UserID,
(SELECT correct_id FROM Item WHERE import_id=item_id) AS ItemID,
created_at,
updated_at
FROM Downloads
This will translate your incorrect user_ids to whatever ID you want to come from the User table and it will do the same for your item_ids. The information coming from SQL will now be correct.
If, however, you want to update the tables with the correct information, you could write this like so:
UPDATE Downloads
SET user_id = User.user_id,
item_id = Item.item_id
FROM Downloads
INNER JOIN User ON Downloads.user_id = User.import_id
INNER JOIN Item ON Downloads.item_id = Item.import_id
WHERE ...
Make sure to put something in the WHERE clause so you don't update every record in the Downloads table (unless that is the plan). I rewrote the above statement to be a bit more optimized since the original version had two SELECT statements per row, which is a bit intense.
Edit:
Since this is PostgreSQL, you can't have the table name in both the UPDATE and the FROM section. Instead, the tables in the FROM section are joined to the table being updated. Here is a quote about this from the PostgreSQL website:
When a FROM clause is present, what essentially happens is that the target table is joined to the tables mentioned in the fromlist, and each output row of the join represents an update operation for the target table. When using FROM you should ensure that the join produces at most one output row for each row to be modified. In other words, a target row shouldn't join to more than one row from the other table(s). If it does, then only one of the join rows will be used to update the target row, but which one will be used is not readily predictable.
http://www.postgresql.org/docs/8.1/static/sql-update.html
With this in mind, here is an example that I think should work (can't test it, sorry):
UPDATE Downloads
SET user_id = User.user_id,
item_id = Item.item_id
FROM User, Item
WHERE Downloads.user_id = User.import_id AND
Downloads.item_id = Item.import_id
That is the basic idea. Don't forget you will still need to add extra criteria to the WHERE section to limit the rows that are updated.
i'm totally guessing from your question, but you have some kind of lookup table that will match an import user_id with the real user_id, and similarly from items. i.e. the assumption is your line of code:
User.find_by_import_id(download.user_id)
hits the database to do the lookup. the import_users / import_items tables are just the names i've given to the lookup tables to do this.
UPDATE downloads
SET downloads.user_id = users.user_id
, downloads.item_id = items.items_id
FROM downloads
INNER JOIN import_users ON downloads.user_id = import_users.import_user_id
INNER JOIN import_items ON downloads.item_id = import_items.import_item_id
Either way (lookup is in DB, or it's derived from code), would it not just be easier to insert the information correctly in the first place? this would mean you can't have any FK's on your table since sometimes they point to one table, and others they point to another. seems a bit odd.