Sql Statement trying to understand join statements - sql

My code is pasted here for the Sql tables and information: http://pastebin.com/GsKp4z30
what I am trying to do is:
SuperClean would like to offer a special to their customers that use coupons. Retrieve the names and
addresses for the customers using coupons on any order from September 1, 2014 through December 24,
2014.
But I keep getting 40+ lines of information and I can't seem to get a join statement to work correctly.
I was trying this but I keep getting invalid identifier.
SELECT
CUSTOMER.CUSTOMER_NAME, CUSTOMER_CUSTOMER_NAME, CUSTOMER.CUSTOMER_ADDRESS
FROM CUSTOMER
INNER JOIN
CUSTOMER ON CUSTOMER.CUSTOMER_ID = CUSTOMER_INVOICE.CUSTOMER_ID;

You have a good first attempt.
Your first problem comes from INNER JOIN CUSTOMER - you are already selecting from CUSTOMER, so why JOIN it with CUSTOMER? You should be joining with CUSTOMER_INVOICE instead:
SELECT
CUSTOMER.CUSTOMER_NAME, CUSTOMER.CUSTOMER_ADDRESS
FROM CUSTOMER
INNER JOIN
CUSTOMER_INVOICE ON CUSTOMER.CUSTOMER_ID = CUSTOMER_INVOICE.CUSTOMER_ID;
I've also fixed the other problem with your SELECT, before it was this:
SELECT
CUSTOMER.CUSTOMER_NAME, CUSTOMER_CUSTOMER_NAME, CUSTOMER.CUSTOMER_ADDRESS
Yet there is no column or alias defined as CUSTOMER_CUSTOMER_NAME. So it will throw you an invalid identifier error.
This will return all of the customers with respective customer invoices - now we need to filter it down to invoices with the coupons set to YES using WHERE:
SELECT
CUSTOMER.CUSTOMER_NAME, CUSTOMER.CUSTOMER_ADDRESS
FROM CUSTOMER
INNER JOIN
CUSTOMER_INVOICE ON CUSTOMER.CUSTOMER_ID = CUSTOMER_INVOICE.CUSTOMER_ID
WHERE
CUSTOMER_INVOICE.COUPON_YESNO = 'YES';
and now filter the result-set down further to work with the particular date range from your question. I'll let you figure this part out unless you're having difficulty understanding the WHERE.

Related

My question is about SQL, using a TOP function inside a sub-query in MS Access

Overall what I'm trying to achieve is a query that shows the most ordered item from a customer in a database. To achieve this I've tried making a query showing how many times a customer has ordered an item, and now I am trying to create a sub-query in it using TOP1 to discern the most bought items.
With the SQL from the first query (looking weird because I made it with the Access automatic creator):
SELECT
Customers.CustomerFirstName,
Customers.CustomerLastName,
Products.ProductName,
COUNT(SalesQuantity.ProductCode) AS CountOfProductCode
FROM (Employees
INNER JOIN (Customers
INNER JOIN Sales
ON Customers.CustomerCode = Sales.CustomerCode)
ON Employees.EmployeeCode = Sales.EmployeeCode)
INNER JOIN (Products
INNER JOIN SalesQuantity
ON Products.ProductCode = SalesQuantity.ProductCode)
ON Sales.SalesCode = SalesQuantity.SalesCode
GROUP BY
Customers.CustomerFirstName,
Customers.CustomerLastName,
Products.ProductName
ORDER BY
COUNT(SalesQuantity.ProductCode) DESC;
I have tried putting in a subquery after FROM line:
(SELECT TOP1 CountOfProduct(s)
FROM (.....)
ORDER by Count(SalesQuantity.ProductCode) DESC)
I'm just not sure what to put in for the "from"-every other tutorial has the data from an already created table, however this is from a query that is being made at the same time. Just messing around I've put "FROM" and then listed every table, as well as
FROM Count(SalesQuantity.ProductCode)
just because I've seen that in the order by from the other code, and assume that the query is discerning from this count. Both tries have ended with an error in the syntax of the "FROM" line.
I'm new to SQL so sorry if it's blatantly obvious, but any help would be greatly appreciated.
Thanks
As I understand, you want the most purchased product for each customer.
So, begin by building aggregate query that counts product purchases by customer (appears to be done in the posted image). Including customer ID in the query would simplify the next step which is to build another query with TOP N nested query.
Part of what complicates this is unique record identifier is lost because of aggregation. Have to use other fields from the aggregate query to provide unique identifier. Consider:
SELECT * FROM Query1 WHERE CustomerID & ProductName IN
(SELECT TOP 1 CustomerID & ProductName FROM Query1 AS Dupe
WHERE Dupe.CustomerID = Query1.CustomerID
ORDER BY Dupe.CustomerID, Dupe.CountOfProductCode DESC);
Overall what I'm trying to achieve is a query that shows the most ordered item from a customer in a database.
This answers your question. It does not modify your query which is only tangentially related.
SELECT s.CustomerCode, sq.ProductCode, SUM(sq.quantity) as qty
FROM Sales as s INNER JOIN
SalesQuantity as sq
ON s.SalesCode = sq.SalesCode
GROUP BY s.CustomerCode, sq.ProductCode;
To get the most ordered items, you can use this twice:
SELECT s.CustomerCode, sq.ProductCode, SUM(sq.quantity) as qty
FROM Sales as s INNER JOIN
SalesQuantity as sq
ON s.SalesCode = sq.SalesCode
GROUP BY s.CustomerCode, sq.ProductCode
HAVING sq.ProductCode IN (SELECT TOP 1 sq2.ProductCode
FROM Sales as s2 INNER JOIN
SalesQuantity as sq2
ON s2.SalesCode = sq2.SalesCode
WHERE s2.CustomerCode = s.CustomerCode
GROUP BY sq2.ProductCode
);
In almost any other database, this would be simpler, because you would be able to use window functions.

Updating table and setting the field values to the result of a left join

I have a table Sales with the field Vendor ("Company A", "Company B", "Trader X"), and I have made a separate table called Vendors with two fields: VendorID and VendorName.
I want to delete the Vendor field in the table Sales and replace it with a VendorID field and fill the fill the field with the corresponding VendorIDs. In other words replace the names of the vendors in the Sales table with their ID from the Vendors table.
I have tried numerous solutions but they do not work. Here is one that I think will work. Some entries in the Sales table do not have any Vendors listed. There are 203 entries and the left join, when run on its own, returns all 203 vendors and the appropriate null values.
Update Sales
Set Sales.VendorID = (Select VendorID From Vendors v Left Join Sales s on
v.VendorName = s.Vendor);
When I run this I get a dialog box asking :
Enter Parameter Value
Or I get the error message :
Operation must use an updateable query
I am using MS Access 2016.
I think that you don't need a subquery, you could just use the UPDATE ... JOIN ... SET syntax, like :
UPDATE sales AS s
INNER JOIN Vendors AS v ON v.VendorName = s.Vendor
SET s.VendorID = v.VendorID

Sum matching entries in SQL

In this database I need to find the total amount that each customer paid for books in a category, and then sort them by their customer ID. The code appears to run correctly but I end up with approximately 20 extra rows than I should, although the sum appears to be correct in the right rows.
The customer ID is part of customer, but is not supposed to appear in the select clause, when I try and ORDER BY it, I get strange errors. The DB engine is DB2.
SELECT distinct customer.name, book.cat, sum(offer.price) AS COST
FROM offer
INNER JOIN purchase ON purchase.title=offer.title
INNER JOIN customer ON customer.cid=purchase.cid
INNER JOIN member ON member.cid=customer.cid
INNER JOIN book ON book.title=offer.title
WHERE
member.club=purchase.club
AND member.cid=purchase.cid AND purchase.club=offer.club
GROUP BY customer.name, book.cat;
You should fix your join conditions to include the ones in the where clause (between table relationships usually fit better into an on clause).
SELECT DISTINCT is almost never appropriate with a GROUP BY.
But those are not your question. You can use an aggregation function:
GROUP BY customer.name, book.cat
ORDER BY MIN(customer.id)

Scalar subquery contains more than one row

Im working with H2 database and wanted to move some data. For that I created the following Query:
UPDATE CUSTOMER
SET EMAIL = SELECT service.EMAIL
FROM CUSTOMER_SERVICE AS service
INNER JOIN CUSTOMER AS customer ON service.ID = customer.CUSTOMER_SERVICE_ID;
When I now perform it in the H2 console I get the following error:
Scalar subquery contains more than one row; SQL statement:
UPDATE CUSTOMER
SET EMAIL = SELECT service.EMAIL
FROM CUSTOMER_SERVICE AS service
INNER JOIN CUSTOMER AS customer ON service.ID = customer.CUSTOMER_SERVICE_ID [90053-192] 90053/90053 (Hilfe)
What is this error telling me?
EDIT
What I want to achiev with my query:
Actually every CUSTOMER has a CUSTOMER_SERVICE. And I simply want to move the COLUMN EMAIL from CUSTOMER_SERVICE to the CUSTOMER Table. for that I already added a email column to the user. I hoped to be able to do it with my query but obviously not.
Your query is not syntactically valid (all subqueries must have parentheses around them).
What you are missing is a correlation clause. I believe you want:
UPDATE CUSTOMER c
SET EMAIL = (SELECT cs.EMAIL
FROM CUSTOMER_SERVICE s
WHERE s.ID = c.CUSTOMER_SERVICE_ID
);
I don't know what this is supposed to be: [90053-192] 90053/90053 (Hilfe).
Your select query is returning more than one row. If you don't want it to, then you need to do something like an aggregate or LIMIT 1 or something similar.
Your sub-query for at least one of your customers has multiple email addresses.
You could ... (Select top 1 serverice.email ...
Or ... (Select max(serverice.email) ...
Update Customer Set EMail=B.Email
From Customer A
Join (Select ID,max(EMail) as EMail From CUSTOMER_SERVICE Group By ID) B
on (A.CUSTOMER_SERVICE_ID = B.ID)
I've spend a lot time with this error type (there shoudn't be duplicates in DB).
At last I've found problem via SQL with COUNT like this:
UPDATE CUSTOMER
SET EMAIL = SELECT COUNT(service.EMAIL)
FROM CUSTOMER_SERVICE AS service
INNER JOIN CUSTOMER AS customer ON service.ID =
customer.CUSTOMER_SERVICE_ID;
And then select problem rows with EMAIL!='1'

Two Tables in SQL Database

beginner sql coder. I have an Access database with a customers table and orders table. The headers of the columns have a space (i.e: Shipped Date). I need to return Company Name, Contact Name, and Phone of customers who placed orders in March of 1998. Shipped Dates are formatted as 01-Mar-1998.
How do I do this? Access keeps giving me errors
SELECT Orders.*,Customers.CompanyName, Customers.ContactName, Customers.Phone
FROM Customers, Orders
(SELECT *
FROM Orders
JOIN Customers ON Orders.Order ID=Customers.Order ID)
AND Shipped Date BETWEEN #03/01/1998# AND #03/31/1998#;
GROUP BY Customers.CompanyName, Customers.ContactName, Customers.Phone;
EDIT:
New code
SELECT *
FROM Orders INNER JOIN Customers ON Orders.Customer=Customers.[Company Name]
WHERE Orders.[Shipped Date] BETWEEN #01-MAR-1998# AND #31-MAR-1998#;
The code runs, but Access prompts me to enter values for the all of the column names...Please help!
Your Query is incorrectly formed. As we should enclose the coloumns with names containing spaces in []
also tour GROUP BY was not relevant.
Now when we use JOIN we should have the query like :
SELECT * FROM Orders JOIN Customers ON Orders.[Order ID]=Customers.[Order ID]
WHERE Orders.[Shipped Date] BETWEEN #03/01/1998# AND #03/31/1998#;