SQL Select statement which shows row-specific count information? - sql

I need some SQL help ..
Suppose I have 2 tables: Customers and Products.
Now, I want to see a SQL statement that will show me these two columns:
Customer | Number of orders placed
How do I do that ?
The second column is a non-existent column, which is showing a number which states how many orders that customer has placed.
For example:
Customer | Number of orders placed
-------- | -----------------------
John | 23
Jack | 5
Mary | 12
etc ..
What's the SQL for this kind of a select ?

I guess that the Product table contains a foreign key CustomerID which references the Customer. The resulting query would be
select Customers.Name, Count(*)
from Customers join Products
on Customers.CustomerID = Products.CustomerID
However, this is just a guess as you forgot to inform us about the relation between the two tables, i.e. how the Products know to which Customer they belong.
Also, but this is a bit picky, you want the number of orders but only have a 'Product' table...

JOIN. This is just making up your column names since tables weren't given.
SELECT
c.Name,
myOrders = COUNT(o.id)
FROM Customers c
INNER JOIN Orders o
ON c.id = o.customerId
GROUP BY c.Name
Some quick reading: JOINS. GROUP BY

Related

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;

Access 2002 SQL for joining three tables

I have been trying to get this to work for a while now. I have 3 tables. First table has the Sales for customers which include the CustomerID, DateOfSales (Which always has the first of the month). The second table has the CustomerName, CustomerID. The third table has which customers buy what product lines. They are stored by CustomerID, ProductID.
I want to get a list (from one SQL hopefully) that has ALL the customers that are listed as buying a certain ProductID AND the maxDate from the Sales. I can get all of them IF there are sales for that customer. How the heck do I get ALL customers that buy the certain ProductID AND the maxDate from Sales or NULL if there is no sales found?
SalesList |CustomerList|WhoBuysWhat
----------|------------|-----------
maxDate |CustomerID |CustomerID
CustomerID| |ProductID=17
This is as close as I got. It gets all max dates but only if there have been sales. I want the CustomerID and a NULL for the maxDate if there were no sales recorded yet.
SELECT WhoBuysWhat.CustomerID, CustomerList.CustomerName,
Max(SalesList.MonthYear) AS MaxOfMonthYear FROM (CustomerList INNER
JOIN SalesList ON CustomerList.CustomerID = SalesList.CustomerID) INNER
JOIN WhoBuysWhat ON CustomerList.CustomerID = WhoBuysWhat.CustomerID
WHERE (((SalesList.ProductID)=17)) GROUP BY WhoBuysWhat.CustomerID,
CustomerList.CustomerName;
Is it possible or do I need to use multiple SQL statements? I know we should get something newer than Access 2002 but that is what they have.
You want LEFT JOINs:
SELECT cl.CustomerID, cl.CustomerName,
Max(sl.MonthYear) AS MaxOfMonthYear
FROM (CustomerList as cl LEFT JOIN
(SELECT sl.*
FROM SalesList sl
WHERE sl.ProductID = 17
) as sl
ON cl.CustomerID = sl.CustomerID
) LEFT JOIN
WhoBuysWhat wbw
ON cl.CustomerID = wbw.CustomerID
GROUP BY cl.CustomerID, cl.CustomerName;

SQL: Join 2 tables and return multiple rows from second table based on key of first table

I have one table 'Customers', with a key of customerid.
There is another table PaymentTotals which also has a customerid column. This table stores amounts paid by a customer (PaymentAmount) in a given week (weeknumber field). This implies that in the PaymentTotals table there may be several rows for any one customerid, the difference being the weeknumber for any of these rows.
I am trying to build a query in MSSQL that joins the two tables and will return for a given customerid the PaymentAmount for each different weeknumber.
It is not clear to me how to build this query. Any advice? Thanks.
SELECT *
FROM Customers C INNER JOIN PaymentTotals PT
ON C.customerid = PT.customerid
If you have multiple Payments made by one customer in a given week and want to get total by week you could do something like ....
SELECT C.customerid
,PT.WeekNumber
,SUM(PT.Payment_Column) AS TotalPayment
FROM Customers C INNER JOIN PaymentTotals PT
ON C.customerid = PT.customerid
GROUP BY C.customerid, PT.WeekNumber

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.

Select count of column grouped by another column SQL

I have two tables, one called Products and one called Products_Category. I want to show the inventory count for each category (grouped by category), and also display the name of the category. The Products table has the inventory count for each Product, but the Products_Category table has the Category names. How can I display the two together? Should I be using some kind of join?
Here's what I'm trying to get:
Category_Name --------- Sum(Products_Inventory)
------Books -------------------- 1 ----------
------Toys---------------------- 2 ----------
But as of right now all I'm able to display is the category ID instead of the category name, like so:
------- 1 ------------------------ 1 ----------
------- 2 ------------------------ 2 ----------
Use JOIN and GROUP BY:
SELECT PC.Category_Name, Sum(P.Products_Inventory)
FROM Products_Category PC
INNER JOIN Products P ON PC.ProductId = P.ProductId
GROUP BY PC.Category_Name
BTW -- This assumes you have a ProductId field in each table. And if I could make a suggestion, you should probably have a Category table as well (better for normalization). Store your ProductId and CateogryId in your Products_Category table.
Good luck.
For these queries I assume product_id is on both tables (you'll have to use the correct field name if I guessed wrong). I'm also using Product_Category.description as the name of the field that has the category names.
This query will get you all categories, and a count of 0 for any product category that's not found in the Product table.
If Product contains one record for each product in stock (ie, 4 books would mean 4 Product records), than COUNT() is the function you want.
SELECT Products_Category.description, COUNT(Product.product_id) AS category_count
FROM Products_Category
LEFT OUTER JOIN Products ON Products_Category.product_id=Products.product_id
GROUP BY Products_Category.description
If Product contains one record for each type product in stock (ie, 4 books would mean 1 record with a product_count of 4), than SUM() is the function you want.
SELECT Products_Category.description, SUM(Product.product_count) AS category_count
FROM Products_Category
LEFT OUTER JOIN Products ON Products_Category.product_id=Products.product_id
GROUP BY Products_Category.description
If you only want records returned when you have inventory in that category, change the LEFT OUTER JOIN to INNER JOIN:
SELECT Products_Category.description, SUM(Product.product_count) AS category_count
FROM Products_Category
INNER JOIN Products ON Products_Category.product_id=Products.product_id
GROUP BY Products_Category.description
the most simplest way is to do this..
SELECT a.Category_Name, Sum(b.Products_Inventory)
FROM Products_Category a, Products b
Where a.ProductId = b.ProductId
GROUP BY a.Category_Name
hope it helps