Error running MS Access delete query with left join - sql

I am using Microsoft Access, I believe from the Office 16 suite.
I am trying to delete records in a Contacts table that are:
listed as "Out of Business" and
no longer have any logged donations in a Donations table.
(We only keep Donations records for five years to maintain a manageable database size. So once an out-of-business company's Donations have worked their way out of that five-year mark, we can go ahead and delete them.)
I've successfully built a query that returns the results I'm looking for - I can see the results in Datasheet view both when doing a SELECT and when switching to DELETE.
However, when I go to run the Delete Query, I get an error message:
Specify the table containing the records you want to delete.
Here is the SQL code:
DELETE Contacts.*
FROM Contacts
LEFT JOIN Donations ON Contacts.[ContactID] = Donations.[DonorID]
WHERE Contacts.ProcurePreference="Out of Business" AND Donations.DonorID Is Null
I am new to SQL code, so am guessing there's something in my syntax that's wonky (although, again, Datasheet view shows exactly what I would expect). Or maybe there's something in the way I've set up my tables and records and relationships that is preventing the final step.
I've searched and read other similar problems on this forum but could not successfully incorporate any of those answers to address my own problem.
Thanks in advance!

You can do what you want with NOT EXISTS:
DELETE Contacts.*
FROM Contacts
WHERE Contacts.ProcurePreference = 'Out of Business'
AND NOT EXISTS (SELECT 1 FROM Donations WHERE Contacts.[ContactID] = Donations.[DonorID])

try using this SQL:
DELETE FROM Contacts
WHERE ProcurePreference = "Out Of Business"
AND ContactId NOT IN (SELECT DonorID FROM Donations)

Related

SQL Database "Operation must use an updateable query" Workaround

So my basic goal is to create a database for a shopsystem, which is my task to do for my IT course. I tried to create a UPDATE-Query, that collects all the Sale Positions ("tblPosition.PositionAnzahl") ordered with a SELECT-Query and groups it by the products ordered, to have an overview about how often each product has been sold.
I want to do this to keep track of how many items are still left in the inventory.
The Query was supposed to update 1 field ("tblArtikel.ArtikelVerkauft") in my table "tblArtikel", in which all my articles and their information is stored.
However, i just found out that you cannot run UPDATE-Queries, that use SELECT-Query data, as i get a error, that says "Operation must use an updateable query".
This is the code i used for the query:
UPDATE tblArtikel as a JOIN
(SELECT p.PositionArtikelID, Sum(p.PositionAnzahl) AS SumOfPositionAnzahl
FROM tblPositionen as p
GROUP BY p.PositionArtikelID
) p
ON a.ArtikelID = p.PositionArtikelID
SET ArtikelVerkauft = p.SumOfPositionAnzahl;
Is there another way to keep track of all the Items left in my inventory, apart from doing what i did?
Here are screenshots of the 2 tables (the depending fields are circled red):
tblPositionen with field PositionAnzahl
tblArtikel with field ArtikelVerkauft
I have not worked with SQL before and only learned about it during 45 min, so ther emight be an easy way for this, but i would still appreciate every answer from you guys.

SQL query / SQL Reporting Services

Been rattling my brain for a while and I could not get pass how to do the SQL query that will show the relationship/connections between my two tables.
I'm working on an IT equipment inventory program. I have two tables;
SELECT serial_number, model, ship_dat, status FROM items_list
SELECT item_serial, connected-to_serial FROM connections
All items like desktops, laptops, monitors, etc are on the items_list table. To track down the relationship/connections of the items, I created the connections table. IE, Monitor with serial_number=Screen#1 is connected to a Desktop with serial_number=Serial#1. It works ok with my Window Form application because I
used a datagridview control to list all devices simple SQL query.
However, when trying to show the relationship/connection on SQL Reports I've ran out of ideas how to do it. I'm aiming to get the report look like below or something along the lines. I just need to show the connections between the items.
Thank you
You should be able to do this with a table in SSRS if that is what you are using. The query you would need to drive the table of all related items would be:
SELECT item_serial, connected-to_serial, mainItem.*, connectedItem.*
FROM connections
INNER JOIN items_list mainItem ON connections.item_serial = items_list.serial_number
INNER JOIN items_list connectedItem ON connections.connected-to_serial = connectedItem.serial_number
You can of course tailor the SELECT statement to your needs, mainItem.* and connectedItem.* will not give you the most descriptive column names. Using column aliases (found under column_alias here) you can give a more descriptive name to each column.
From here you should be able to use a table and create a row group on the main item (either name or serial number) to get the type of look you are looking to achieve here. I believe the Report Wizard actually has most of the functionality you are looking for and should handle the bulk of this. You may have to move some of the cells around to get the look you are going for though.

How to remove row that exists in another table?

I have two tables. Main table is "CompleteEmailListJuly11" and the second table is "CurrentCustomersEmailJuly11". I want to delete rows in CompleteEmailListJuly11 table that CurrentCustomersEmailJuly11 has based off email.
I've tried this following Delete example, but it doesn't do anything close to what I'm trying to do. This only shows me the ones that EXIST in the database, it doesn't show me the the list of emails that AREN'T matching.
DELETE * FROM CompleteEmailListJuly11 AS i
WHERE EXISTS (
SELECT 1 FROM CurrentCustomersEmailJuly11
WHERE CurrentCustomersEmailJuly11.email = i.EmailAddress
)
Help is greatly appreciated.
This is the query I think you need:
DELETE FROM CompleteEmailListJuly11
WHERE EmailAddress IN (SELECT email FROM CurrentCustomersEmailJuly11)
Ps: The DELETE query does not delete individual fields, only entire rows, so the * is not necessary, you will also need to "Execute" this query rather than "Previewing" or "Exporting"
If you're building your DELETE query in Access' query designer, notice there are two different modes of operation which seem similar to "go ahead and do this".
Datasheet View (represented by the grid icon labeled "View" on the "Design" section of the ribbon). That view enables you to preview the affected records, but does not actually delete them.
The "Run" icon (represented by a red exclamation point). "Run" will actually execute the query and delete the affected records.
If you already know this, my description may seem insulting. Sorry. However, it seems that folks new to Access can easily overlook the distinction between them.
You can use something like this adapted to delete
SELECT ... // complete
EXCEPT
SELECT ... // current
I am not sure exactly how it maps to delete but take a look at that.
I fond it in a similar question: How do I 'subtract' sql tables?
We can use Correlated Query to resolve the issue like
DELETE FROM COMPLETE C
WHERE EMAIL = (SELECT EMAIL FROM CURR CU WHERE CU.EMAIL=C.EMAIL);

sql update multiple rows with multi join subselect

This is an updated part 2 of a question I asked earlier. I'm trying to make the following update, but this query does not actually seem to do anything.
UPDATE u
SET graduation_class_id = gc.graduation_class_id
FROM [user] u
JOIN graduation_class gc
ON u.graduation_class_id = gc.graduation_class_id
JOIN graduation_term gt
ON gt.graduation_year_id = gc.graduation_year_id
TABLE SCHEMA
**user
user_id
graduation_class_id
**graduation_class
graduation_class_id
graduation_year_id
**graduation_term
graduation_term_id
graduation_year_id
The goal is to get the matching graduation_class_id value into the user table. I've been told this won't work because the match won't be found unless the user already has the matching graduation_class_id. That is a problem, because I'm trying to actually get the proper one in there!
This idea is fundamentally doomed to fail. You're trying to get the SQL server to link a graduation class to a user by itself, despite the SQL server not having information on which graduation class should be linked to the user. Unless you have some data somewhere (in user, in graduation_class, in some other table) that links a user_id to the graduation term, class, or year (or someone manually telling SQL which data match up), SQL can't magically do that job for you.

Please help me make this Access 2007 Friendly

I asked a friend to hellp me with an issue I was having with my Access Database since I haven't programmed in years, and here's what he replied with:
Let me toss an example out just to make sure I'm looking at this
right. You start with a record with ID 1. This gets renewed, and the
system generates a new record with ID 2, and brings along the old ID
of 1 in the RenewalOf field, and so on for future renewals. If that
is correct, and each record is only allowed to be referenced once (so
there will only ever be one record with ID of 1 in the RenewalOf
field), then the following should work:
This bit of code didn't work:
UPDATE
tblSold
SET
RenewedToID = RenewalRecord.SoldID
FROM
tblSold
INNER JOIN tblSold RenewalRecord ON
tblSold.SoldID = RenewalRecord.RenewalOf
Not sure what is allowed in your SQL queries, but this is basic and
should be fine. You can also add in some criteria to only update
records where the RenewedToID field is blank, or only for one record
if you are processing this just after you add a new record. You can
check to make sure this is going to work by running the following:
But this did:
SELECT
tblSold.SoldID
,RenewalRecord.SoldID
FROM
tblSold
INNER JOIN tblSold RenewalRecord ON
tblSold.SoldID = RenewalRecord.RenewalOf
This will list the original ID along with the renewal ID, i.e. the one
that will be put in the original record. Let me know if this works or
if you have any issues with it.
Can you help me make his first code snippet work in Access 2007?
You may need to rearrange the update slightly for Access:
UPDATE
tblSold
INNER JOIN tblSold RenewalRecord ON
tblSold.SoldID = RenewalRecord.RenewalOf
SET
tblSold.RenewedToID = RenewalRecord.SoldID
Some other SO answers showing this type of syntax:
SQL Update Statement in MS Access
How to create a correlated update subquery in MS-Access?