Create a stored procedure to delete rows that have no values - sql

Create a stored procedure called sp_del_inactive_cust to delete customers that have no orders. The stored procedure should delete 1 row.
Here is the database I am working with.
(source: bcitwebdev.com)
My immediate thought is that I need to check the customers table against the orders table. If the customer is present in the customers table but not in the orders table, that must mean that they have not created any order ids under their customer id. Then, I must delete the customer if they do not have any orders.
I'm not really sure how to go about scripting this problem. I need help! Please keep it simple as I am a first semester student.
Here's something I've tried starting:
CREATE PROCEDURE sp_del_inactive_cust
AS
SELECT customers.customer_id,
orders.customer_id
FROM customers
INNER JOIN orders ON customers.customer_id=orders.customer_id
WHERE /* customer_id is found in customers table but not in orders table */
And then I will execute the procedure.
This question has been answered thanks to the help of Michael Fredrickson.
Here are the final statements which deleted the required 1 row:
CREATE PROCEDURE sp_del_inactive_cust
AS
DELETE customers
FROM customers
LEFT OUTER JOIN orders ON customers.customer_id = orders.customer_id
WHERE orders.customer_id IS NULL;
GO
EXECUTE sp_del_inactive_cust;
GO

CREATE PROCEDURE sp_del_inactive_cust
AS
DELETE TOP (1) c
FROM
customers c
LEFT OUTER JOIN orders o
ON C.customer_id = o.customer_id
WHERE
o.customer_id IS NULL

You will want to create an anti-join to get the customers that have placed no orders, like this:
DELETE c FROM
FROM customers c LEFT JOIN orders o ON c.customer_id = o.customer_id
WHERE o.customer_id IS NULL

I hate to just give you the answer so I will give you an example of the inverse and let you figure out the rest
here is an example
2 tables
foo {foo_id, a, b, c}
bar {bar_id, foo_Id, e, f, g}
If i want to delete all records from foo that appear in the bar table I would write
delete foo
where foo_id in (select foo_id from bar)
look up the "in" keyword for a real explanation
also there are always many ways of doing something and you might not get the proper grade in a class if you dont do things the way the teacher wants

DELETE customers
WHERE customer_id NOT IN (SELECT customer_id FROM Orders)

Related

Still can't delete in SQL using JOIN

I am using PostgreSQL. I saw other posts with people having trouble using join while deleting, which said to specify the table you are deleting from. I did that, and this is still not working. It says there is a "syntax error at or near 'Customers'. I am using the famous Northwind database.
DELETE Customers FROM Customers INNER JOIN Orders
ON Customers.CustomerID=Orders.CustomerID
WHERE Customers.CustomerID = 5;
The code doesn't really do anything useful, I just want to know why I can't delete using JOIN.
As documented in the manual you can't use JOIN like that in a DELETE statement. To join tables to the base table you need to use the USING clause:
DELETE FROM Customers
using Orders
where Customers.CustomerID=Orders.CustomerID
and Customers.CustomerID = 5;
This is equivalent to the SQL without a join:
delete from customers as c
where c.customerid = 5
and exists (select *
from orders o
where o.customerid = c.customerid);
A join in a delete will never work. If you want to ensure that the customer has an order, you could try something like this:
DELETE FROM Customers
WHERE
CustomerID = 5 AND
CustomerID IN (SELECT o.CustomerID FROM Orders o);

Oracle SQL Query - Include customer in query if they have more than 3 items across multiple orders

EDIT: Added the query I came up with.
I'm a beginner at SQL (having it be taught as part of a database management class I am currently taking). One of my projects is to create a database revolving around customers and their orders. For this project, I have to make four tables:
Customer (PK = CustomerID),
Invoice (PK = InvoiceID/ FK = CustomerID),
Product (PK = ProductSKU), and
Invoice_Item (PK = FK Invoice ID + FK ProductSKU).
I have to make a query that asks the question of "What customers have ordered more than 3 of a certain item?" The query contains the fields of the CustomerID (C_ID), CustomerName (C_BUS), InvoiceID (I_NUM), ProductSKU (P_SKU), and ProductAmountOrdered (II_ORDERED) (attribute of the Invoice_Item table). Also note that the Invoice_ID and ProductSKU attributes in the query are coming from the Invoice_Item table. Now, I answered the question with the help of some joins, but there is a catch. The customer still satisfies the criteria if they have ordered more than 3 items across multiple orders (say they order 2 in one order and 2 in another). This is the part that is tripping me up. What is the best way to go about doing this? I have looked around and haven't found anything that seems like it would solve this question. Any help wold be greatly appreciated!
Here is the code that I have so far:
SELECT CUSTOMER.C_ID, C_BUS, P_SKU, INVOICE.I_NUM, INVOICE_ITEM.II_ORDERED
FROM CUSTOMER, INVOICE, INVOICE_ITEM
WHERE CUSTOMER.C_ID = INVOICE.C_ID
AND INVOICE.I_NUM = INVOICE_ITEM.I_NUM
AND INVOICE_ITEM.P_SKU = 'P0548'
AND II_ORDERED > 3
ORDER BY C_BUS DESC;
I understand that this might not be the best syntax, but this is what I managed using my textbook as a reference.
Please modify the queries as per your naming standards.
query for the customers who ordered more then three of a certain item across all their invoices:
select c.customer_id,
c.customer_name,
ii.product_sku,
sum(ii.ProductAmountOrdered)
as total_quantity_ordered
from customer c
inner join invoice i on c.customer_id = i.customer_id
inner join invoice_item ii on i.invoice_id = ii.invoice_id
group by c.customer_id,
c.customer_name,
ii.product_sku
having sum(ii.ProductAmountOrdered) >= 3;
Query to fetch customers that ordered more then 3 of a product in a single order/invoice:
select c.customer_id,
c.customer_name,
ii.invoice_id,
ii.product_sku,
sum(ii.ProductAmountOrdered)
as total_quantity_ordered
from customer c
inner join invoice i on c.customer_id = i.customer_id
inner join invoice_item ii on i.invoice_id = ii.invoice_id
group by c.customer_id,
c.customer_name,
ii.invoice_id,
ii.product_sku
having sum(ii.ProductAmountOrdered) >= 3;

A simple nested SQL statement

I have a question in SQL that I am trying to solve. I know that the answer is very simple but I just can not get it right. I have two tables, one with customers and the other one with orders. The two tables are connected using customer_id. The question is to list all the customers that did not make any order! The question is to be run in MapInfo Professional, a GIS desktop software, so not every SQL command is applicable to that program. In other words, I will be thankful if I get more than approach to solve that problem.
Here is how I have been thinking:
SELECT customer_id
from customers
WHERE order_id not in (select order_id from order)
and customer.customer_id = order.customer_id
How about this:
SELECT * from customers
WHERE customer_id not in (select customer_id from order)
The logic is, if we don't have a customer_id in order that means that customer has never placed an order. As you have mentioned that customer_id is the common key, hence above query should fetch the desired result.
SELECT c.customer_id
FROM customers c
LEFT JOIN orders o ON (o.customer_id = c.customer_id)
WHERE o.order_id IS NULL
... The NOT EXISITS way:
SELECT * FROM customers
WHERE NOT EXISTS (
SELECT * FROM orders
WHERE orders.customer_id = customer.customer_id
)
There are some problems with your approach:
There is probably no order_id in the customers table, but in your where-statement you refer to it
The alias (or table-name) order in the where-statement (order.customer_id) is not known because there is no join statement in there
If there would be a join, you would filter out all customers without orders, exactly the opposite of what you want
Your question is difficualt to answer to me because I do not know which SQL subset MapInfo GIS understands, but lets try:
select * from customers c where not exists (select * from order o where o.customer_id=c.customer_id)

Return customers with no sales

I'm a bit of a beginner with SQL so apologies if this seems trivial/basic. I'm struggling to get my head around it...
I am trying to generate results that show all customers that are in the customer table that have never placed an order and will therefore have no entry on the invoice table.
In other words, I want to select all customers from the customer table where there is no entry for their customer number in the invoice table.
Many thanks,
Mike
SELECT *
FROM customer c
WHERE NOT EXISTS (
SELECT 1
FROM invoice i
WHERE i.customerid = c.customerid
)
I would suggest you also read Oracle's documentation on different types of table joins here.
if customer_id is the collumn that identify the customer you should do something like this...
select * from Customer
where customer_id not in (select customer_id from invoice)
If you want to return all customer rows, then you will want to use a LEFT JOIN
select *
from customer c
left join invoices i
on c.customerid = i.customerid
where i.customerid is null
See SQL Fiddle with Demo
If you need help learning JOIN syntax, then here is a great visual explanation of joins.
A LEFT JOIN will return all rows from the customer table even if there is not a matching row in the invoices table. If you wanted to return only the rows that matched in both tables, then you would use an INNER JOIN. By adding the where i.customerid is null to the query it will return only those rows with no match in invoices.

Problem in sql query

I have two tables called customer and items.
With single query I want to get all the custid and customername whose custid='Custid1' and itemid whose custid='Custid1'.
How can I build this query?? custid is the primary key of customer table. custid is the foreign key of items table.
I have written this query its not listing all the custid, only listing custid thrice... Here is my query:
create procedure spGetCustomer
as
begin
select a.custid, a.custname,b.itemid
from customer a inner join items b on a.custid = b.custid
WHERE b.custid='custid1'
end
Your question isn't quite clear - what is it you really want??
The JOIN you have will list all customers with items where the customer.custid is custid1. But that doesn't seem to be what you're looking for.....
Could it be you're looking for all customers - with or without items - that have a specific custid?? Try something like this:
SELECT
c.custid, c.custname, i.itemid
FROM
dbo.customer c
LEFT OUTER JOIN
dbo.items i ON c.custid = i.custid
WHERE
c.custid = 'custid1'
If the items.custid is indeed a foreign key into the customer table, there shouldn't be any items around that have custid = custid1 that aren't joined to an existing customer.
If your question actually relates to how you pass the parameter in, your proc should be:
create procedure spGetCustomer(#custid1 varchar(100))
as
begin
select a.custid, a.custname,b.itemid
from customer a inner join items b on a.custid = b.custid
WHERE b.custid=#custid1
end