SQL Developer QUERY For uni assignment - sql

I am stuck with the following queries. Anyone can help?
Show the full name and the phone number of the customer who made the most orders.
Which item is the best seller? Display description and price.
Attached is my ERD.
create table statements are as follows:
CREATE TABLE ITEMS (
itemID number(5),
itemDescription varchar2(60),
itemSize varchar2(22),
itemColour varchar2(10),
itemPrice number (5,2),
itemQuantityAvailable number(3),
CONSTRAINT pk_items PRIMARY KEY (itemID));
CREATE TABLE CUSTOMERS (
custID number(5),
custLName varchar2(10),
custFName varchar2(20),
custAddress varchar2(30),
custTown varchar2(20),
custPostcode number(4),
custPhone number(10),
custEmail varchar2(30),
shopID number(5),
CONSTRAINT pk_customers PRIMARY KEY (custID),
CONSTRAINT fk_customers_shopID FOREIGN KEY (shopID)
REFERENCES SHOPS (shopID));
CREATE TABLE ORDERS (
orderNo number(5),
orderDate Date,
dispatchDate date,
custID number(5),
CONSTRAINT pk_orders PRIMARY KEY (orderNo),
CONSTRAINT fk_orders_custID FOREIGN KEY (custID)
REFERENCES CUSTOMERS (custID));
CREATE TABLE OrderQuantity (
orderNo number(5),
itemID number(5),
orderQuantity number(3),
CONSTRAINT pk_orderQty PRIMARY KEY (itemID, orderNo),
CONSTRAINT fk_orderQty_itemID FOREIGN KEY (itemID)
REFERENCES ITEMS (itemID),
CONSTRAINT fk_orderQty_orderNo FOREIGN KEY (orderNO)
REFERENCES ORDERS (orderNo));
INSERT STATEMENTS ARE AS FOLLOWS:
INSERT INTO ITEMS VALUES (1,'ADIDAS MEN''S ID STADIUM FULL-ZIP JACKET','S/M/L/XL','Silver',89.99,100);
INSERT INTO ITEMS VALUES (2,'ADIDAS MEN''S ESSENTIALS 3 STRIPES CREW FRENCH TERRY','S/L/XL','Black',71.99,90);
INSERT INTO ITEMS VALUES (3,'ADIDAS MEN''s ESSENTIALS 3-STRIPES FLEECE PANT','M/L/XL/XXL','White',62.99,80);
INSERT INTO ITEMS VALUES (4,'NIKE MEN''S FULL-ZIP SPORTSWEAR HOODIE','M/L/XL','DarkGrey',67.49,70);
INSERT INTO ITEMS VALUES (5,'NIKE MEN''S HBR FLEECE CREW','S/L/XL','DarkGrey',58.49,60);
INSERT INTO ITEMS VALUES (6,'PUMA MEN''S ESSENTIAL SWEAT PANTS','XS/S/M/L/XL','Navy',45.00,50);
INSERT INTO ITEMS VALUES (7,'ADIDAS MEN''S ESSENTIALS CHELSEA SHORTS','M/L/XL','Green',35.99,40);
INSERT INTO ITEMS VALUES (8,'PUMA MEN''S CORE 7IN RUNNING SHORTS','S/L/XL','Black',26.99,20);
INSERT INTO ITEMS VALUES (9,'ASICS GT 2000 6 MEN''S RUNNING SHOES','8/8.5/9/9.5/10','Silver',239.00,90);
INSERT INTO ITEMS VALUES (10,'ASICS GEL-KAYANO 25 2E WIDE MEN''S RUNNING SHOE','9/9.5/10/10.5/11','Black',219.00,60);
INSERT INTO ITEMS VALUES (11,'REEBOK RUNNER 3.0 MEN''S RUNNING SHOES','8/8.5/10/10.5','Orange',209.00,10);
INSERT INTO ITEMS VALUES (12,'REEBOK MEN''S WORKOUT READY 2.0 TEE','XS/S/M','White',199.00,50);
INSERT INTO ITEMS VALUES (13,'UNDER ARMOUR RAPID MEN''S RUNNING SHOES','8.5/10/11','Black',199.00,20);
INSERT INTO ITEMS VALUES (14,'UNDER ARMOUR CHARGED MEN''S RUNNING SHOES','8/8.5/9/9.5/10','Silver',159.00,80);
INSERT INTO ITEMS VALUES (15,'ADIDAS SOLAR DRIVE MEN''S RUNNING SHOE','8/8.5/10/10.5','Black',139.00,30);
INSERT INTO CUSTOMERS VALUES (1,'Widimer','Cindy','121 King St','Box Hill',3195,0470121566,'cindy_widimer#gmail.com',1);
INSERT INTO CUSTOMERS VALUES (2,'Bohrman','Robert','54 Queens St','Murrumbeena',3195,0455131565,'robert_bohram#gmail.com',3);
INSERT INTO CUSTOMERS VALUES (3,'Clarke','Brenda','89 Pecket St','Oakleigh',3195,0424456123,'brenda.clarke#gmail.com',2);
INSERT INTO CUSTOMERS VALUES (4,'Cartier','Bruce','12 Parkore St','Mulgrave',3195,0425654123,'bruce.cartier#gmail.com',3);
INSERT INTO CUSTOMERS VALUES (5,'Heart','Lucy','45 Rose St','Hampton Park',3178,0470456321,'lucy.heart#gmail.com',1);
INSERT INTO CUSTOMERS VALUES (6,'Carter','Joan','123 Davdison St','Hampton Park',3178,0452123789,'carter_joangmail.com',3);
INSERT INTO CUSTOMERS VALUES (7,'John','Ailene','56 Spring St','Yaraman',3178,0475123159,'john.ailene#gmail.com',1);
INSERT INTO CUSTOMERS VALUES (8,'Lewis','Carl','45 Brendon Ct','Noble Park',3178,0454789456,'carl_lewis#gmail.com',3);
INSERT INTO CUSTOMERS VALUES (9,'Holden','Hilary','56 Swanston St','Sunshine',3020,0421456123,'hilar_holdengmail.com',1);
INSERT INTO CUSTOMERS VALUES (10,'Powell','Venus','124 Russel St','Richmond',3112,0431456753,'venus_powellgmail.com',2);
INSERT INTO CUSTOMERS VALUES (11,'Juliet','Susan','87 Fawkner Ct','South Yara',3141,0424687423,'susan_juliet#gmail.com',2);
INSERT INTO CUSTOMERS VALUES (12,'Price','Victor','125 William St','Flagstaff',3003,0465789123,'victor_price#gmail.com',2);
INSERT INTO ORDERS VALUES (1,'01/Jan/18','03/Feb/18',1);
INSERT INTO ORDERS VALUES (2,'20/Jan/18','05/Feb/18',3);
INSERT INTO ORDERS VALUES (3,'05/Feb/18','10/Feb/18',4);
INSERT INTO ORDERS VALUES (4,'18/Feb/18','22/Feb/18',5);
INSERT INTO ORDERS VALUES (5,'01/Mar/18','10/Mar/18',10);
INSERT INTO ORDERS VALUES (6,'12/Mar/18','15/Mar/18',12);
INSERT INTO ORDERS VALUES (7,'07/Apr/18','14/Apr/18',11);
INSERT INTO ORDERS VALUES (8,'25/Apr/18','27/Apr/18',3);
INSERT INTO ORDERS VALUES (9,'06/May/18','10/May/18',2);
INSERT INTO ORDERS VALUES (10,'17/Jun/18','20/Jun/18',5);
INSERT INTO ORDERS VALUES (11,'29/Jun/18','07/Jul/18',4);
INSERT INTO ORDERS VALUES (12,'08/Jul/18','14/Jul/18',11);
INSERT INTO ORDERS VALUES (13,'25/Jul/18','29/Jul/18',12);
INSERT INTO ORDERS VALUES (14,'01/Aug/18','18/Aug/18',5);
INSERT INTO ORDERS VALUES (15,'19/Aug/18','10/Sep/18',1);
INSERT INTO ORDERS VALUES (16,'11/Sep/18','15/Sep/18',4);
INSERT INTO ORDERS VALUES (17,'21/Sep/18','29/Sep/18',5);
INSERT INTO ORDERS VALUES (18,'01/Oct/18',null,10);
INSERT INTO ORDERS VALUES (19,'20/Oct/18',null,3);
INSERT INTO ORDERS VALUES (20,'23/Oct/18',null,1);
INSERT INTO OrderQuantity VALUES (1,1,20);
INSERT INTO OrderQuantity VALUES (2,3,10);
INSERT INTO OrderQuantity VALUES (3,4,20);
INSERT INTO OrderQuantity VALUES (4,5,14);
INSERT INTO OrderQuantity VALUES (5,10,10);
INSERT INTO OrderQuantity VALUES (6,11,15);
INSERT INTO OrderQuantity VALUES (7,12,10);
INSERT INTO OrderQuantity VALUES (8,3,25);
INSERT INTO OrderQuantity VALUES (9,2,50);
INSERT INTO OrderQuantity VALUES (10,5,20);
INSERT INTO OrderQuantity VALUES (11,4,10);
INSERT INTO OrderQuantity VALUES (12,11,20);
INSERT INTO OrderQuantity VALUES (13,12,10);
INSERT INTO OrderQuantity VALUES (14,5,10);
INSERT INTO OrderQuantity VALUES (15,1,10);
INSERT INTO OrderQuantity VALUES (16,4,30);
INSERT INTO OrderQuantity VALUES (17,5,9);
INSERT INTO OrderQuantity VALUES (18,10,30);
INSERT INTO OrderQuantity VALUES (19,3,20);
INSERT INTO OrderQuantity VALUES (20,1,15);

This is a simple example of how to solve it by making a subquery and only select the first row from it.
SELECT full_name, custPhone
FROM (SELECT CONCAT(custFName, ' ', custLName) as full_name, custPhone, COUNT(o.orderNo) num_orders
FROM ORDERS o
JOIN Customers c ON c.custId = o.custid
GROUP BY full_name, custPhone
ORDER BY num_orders Desc ) AS subq
WHERE ROWNUM = 1
and the same for the second query
SELECT itemDescription, itemPrice
FROM (SELECT itemDescription, itemPrice, SUM(orderQuantity) sum_quantity
FROM OrderQuantity o
JOIN Items i ON i.itemId = o.itemId
GROUP BY itemDescription, itemPrice
ORDER BY sum_quantity DESC) AS subq
WHERE ROWNUM = 1

check this sqlfiddle http://sqlfiddle.com/#!5/553399/39/0
The Full name and the phone number of the customers who made the most orders :
SELECT ORDERS.custID,CUSTOMERS.custFName,CUSTOMERS.custPhone,COUNT(ORDERS.orderNo )
FROM ORDERS inner join CUSTOMERS
on CUSTOMERS.custID =ORDERS.custID
group by ORDERS.custID,CUSTOMERS.custFName,CUSTOMERS.custPhone
order by COUNT(ORDERS.orderNo ) desc
Description and price of Bestseller Item (qty bestseller):
SELECT OrderQuantity.itemID ,ITEMS.itemDescription,ITEMS.itemPrice ,sum(distinct OrderQuantity.itemID )
FROM OrderQuantity inner join ITEMS
on OrderQuantity.itemID =ITEMS.itemID
GROUP BY OrderQuantity.itemID ,ITEMS.itemDescription,ITEMS.itemPrice
ORDER BY sum(distinct OrderQuantity.itemID) DESC
if you need only top bestseller item you can add rownum 1 to these queries.
select * from (SELECT OrderQuantity.itemID ,ITEMS.itemDescription,ITEMS.itemPrice ,sum(distinct OrderQuantity.itemID )
FROM OrderQuantity inner join ITEMS
on OrderQuantity.itemID =ITEMS.itemID
GROUP BY OrderQuantity.itemID ,ITEMS.itemDescription,ITEMS.itemPrice
ORDER BY sum(distinct OrderQuantity.itemID) DESC) q
Where rownum=1

Related

How to display a DVD that has been purchased by all customers in SQL Server?

Below are the tables I have created + I have also inserted data in all the tables:
CREATE DATABASE DVD_Transaction
CREATE TABLE DVD
(
DVD_No INTEGER IDENTITY(1,1) PRIMARY KEY,
DVD_Name VARCHAR(50) UNIQUE NOT NULL
)
INSERT INTO DVD (DVD_Name)
VALUES ('School of Rock')
INSERT INTO DVD (DVD_Name)
VALUES ('Rock Dog 1')
INSERT INTO DVD (DVD_Name)
VALUES ('Rock Dog 2')
INSERT INTO DVD (DVD_Name)
VALUES ('Coco')
INSERT INTO DVD (DVD_Name)
VALUES ('Luca')
CREATE TABLE Customer
(
Customer_No INTEGER IDENTITY(1,1) PRIMARY KEY,
Customer_Name VARCHAR(50) UNIQUE NOT NULL
)
INSERT INTO Customer (Customer_Name)
VALUES ('Bill Gates')
INSERT INTO Customer (Customer_Name)
VALUES ('Larry Ellison')
INSERT INTO Customer (Customer_Name)
VALUES ('Steve Jobs')
INSERT INTO Customer (Customer_Name)
VALUES ('Jeff Bezos')
INSERT INTO Customer (Customer_Name)
VALUES ('Elon Musk')
INSERT INTO Customer (Customer_Name)
VALUES ('David Gilmour')
CREATE TABLE DVD_Purchase
(
DVD_Purchase_No INTEGER IDENTITY(1,1) PRIMARY KEY,
Customer_No INTEGER NOT NULL FOREIGN KEY REFERENCES Customer(Customer_No),
DVD_No INTEGER NOT NULL FOREIGN KEY REFERENCES DVD(DVD_No)
)
INSERT INTO DVD_Purchase (Customer_No,DVD_No)
VALUES(1,1)
INSERT INTO DVD_Purchase (Customer_No,DVD_No)
VALUES(1,2)
INSERT INTO DVD_Purchase (Customer_No,DVD_No)
VALUES(1,3)
INSERT INTO DVD_Purchase (Customer_No,DVD_No)
VALUES(1,4)
INSERT INTO DVD_Purchase (Customer_No,DVD_No)
VALUES(1,5)
INSERT INTO DVD_Purchase (Customer_No,DVD_No)
VALUES(2,1)
INSERT INTO DVD_Purchase (Customer_No,DVD_No)
VALUES(2,2)
INSERT INTO DVD_Purchase (Customer_No,DVD_No)
VALUES(2,3)
INSERT INTO DVD_Purchase (Customer_No,DVD_No)
VALUES(2,4)
INSERT INTO DVD_Purchase (Customer_No,DVD_No)
VALUES(3,1)
INSERT INTO DVD_Purchase (Customer_No,DVD_No)
VALUES(3,2)
INSERT INTO DVD_Purchase (Customer_No,DVD_No)
VALUES(3,3)
INSERT INTO DVD_Purchase (Customer_No,DVD_No)
VALUES(4,1)
INSERT INTO DVD_Purchase (Customer_No,DVD_No)
VALUES(4,2)
INSERT INTO DVD_Purchase (Customer_No,DVD_No)
VALUES(5,1)
Then I ran the following query to see which Customer purchased which DVD product:
SELECT Customer_Name,DVD_Name
FROM Customer,DVD,DVD_Purchase
WHERE Customer.Customer_No = DVD_Purchase.Customer_No
AND DVD.DVD_No = DVD_Purchase.DVD_No
It shows the following the result where:
Bill Gates purchased 5 DVD
Larry Ellison purchased 4 DVD
Steve Jobs purchased 3 DVD
Jeff Bezos purchased 2 DVD
Elon Musk purchased 1 DVD
I successfully ran a query to show a customer that has purchased all DVD:
SELECT DISTINCT Customer_Name
FROM Customer, DVD_Purchase
WHERE Customer.Customer_No = DVD_Purchase.Customer_No
AND Customer.Customer_No IN
(SELECT Customer_No
FROM DVD_Purchase
GROUP BY Customer_No
HAVING COUNT(DISTINCT DVD_No) = (SELECT COUNT(*) FROM DVD)
)
The query result shows that Bill Gates is the customer who has purchased all DVD
Now, I tried to run a query to show a DVD that has been purchased by all customers.
SELECT DISTINCT DVD_Name
FROM DVD, DVD_Purchase
WHERE DVD.DVD_No = DVD_Purchase.DVD_No
AND DVD.DVD_No IN
(SELECT DVD_No
FROM DVD_Purchase
GROUP BY DVD_No
HAVING COUNT(DISTINCT Customer_No) = (SELECT COUNT(*) FROM Customer)
)
Now I am getting blank result.
I am still not able to figure out why I am getting blank result.
What mistake am I possibly making here ?
Any recommended solution would be highly appreciated.
Your last query does not return results because this sub-query does not return results:
SELECT DVD_No
FROM DVD_Purchase
GROUP BY DVD_No
HAVING COUNT(DISTINCT Customer_No) = (SELECT COUNT(*) FROM Customer)
You have 6 customers (result from: SELECT COUNT(*) FROM Customer)
And the number of DVD_Purchase is:
SELECT DVD_No, COUNT(DISTINCT Customer_No)
FROM DVD_Purchase
GROUP BY DVD_No
result:
DVD_No
count
1
5
2
4
3
3
4
2
5
1
There is no DVD that is being purchased 6 times...
I have finally solved the problem:
All I had to add in the sub-query was:
(SELECT DVD_No
FROM DVD_Purchase
GROUP BY DVD_No
HAVING COUNT(DISTINCT Customer_No) =
(SELECT COUNT (*) FROM Customer
WHERE Customer.Customer_No IN
(SELECT Customer_No FROM DVD_Purchase)
)
)

Update column in Invoice Table with Payment total from Payments table

I've got 2 tables (shown below) - Invoice and Payments. A single invoice can have multiple payments. I need to SUM the total of PayAmt from Payments and update the PayTotal column in the Invoice table.
This is NOT working:
UPDATE Invoices
SET Invoices.PayTotal = Payments.Total
FROM Invoices
INNER JOIN
(SELECT InvNum_FK, SUM(PayAmt) as Total
FROM Payments) ON Invoices.InvNum_PK = Payments.InvNum_FK
CREATE TABLE dbo.Invoices
(
InvNum_PK nvarchar(255) PRIMARY KEY,
InvAmt money,
InvDate date,
CustName nvarchar(255),
PayTotal money,
PayCount int
);
CREATE TABLE dbo.Payments
(
PayNum_PK int PRIMARY KEY,
InvNum_FK nvarchar(255)
FOREIGN KEY REFERENCES dbo.Invoices(InvNum_PK),
PayAmt money,
PayDate date,
);
INSERT INTO Invoices
VALUES ('GLI101', 838.93, '2021-08-01', 'George Washington', 0, 0);
INSERT INTO Invoices
VALUES ('GLI202', 1280.26, '2021-08-02', 'Abe Lincoln', 0, 0);
INSERT INTO Invoices
VALUES ('GLI303', 1456.23, '2021-08-03', 'Tom Jefferson', 0, 0);
INSERT INTO Invoices
VALUES ('GLI404', 1124.97, '2021-08-04', 'Jim Madison', 0, 0);
INSERT INTO Payments VALUES (1, 'GLI101', 223.33, '08/15/2021')
INSERT INTO Payments VALUES (2, 'GLI101', 211.88, '09/16/2021')
INSERT INTO Payments VALUES (3, 'GLI101', 316.44, '09/14/2021')
INSERT INTO Payments VALUES (4, 'GLI404', 415.46, '09/10/2021')
INSERT INTO Payments VALUES (5, 'GLI404', 115.46, '09/04/2021')
This works if anyone looks at this post in the future with the same question:
WITH cte AS (
SELECT InvNum_FK, SUM(PayAmt) AS PayTotal
FROM Payments
GROUP BY InvNum_FK)
UPDATE Invoices SET Invoices.PayTotal = cte.PayTotal
FROM Invoices INNER JOIN cte ON Invoices.InvNum_PK = cte.InvNum_FK

Query to get latest datetime for 2 columns individually

create table Orders
(
city varchar(5)
,orderid int
,OrderedDateTime datetime
,ThresholdDatetime datetime
)
insert into Orders values ('Texas',23,'2017-08-24 12:20:56.560','2017-08-24 20:00:23.000')
insert into Orders values ('Texas',23,'2017-08-24 13:20:45.560','2017-08-24 22:20:23.000')
insert into Orders values ('Texas',23,'2017-08-24 16:20:45.560','2017-08-24 20:00:23.000')
insert into Orders values ('Texas',23,'2017-08-24 17:20:23.560','2017-08-24 22:00:23.000')
insert into Orders values ('Texas',23,'2017-08-23 12:20:23.560','2017-08-23 14:00:23.000')
insert into Orders values ('Texas',23,'2017-08-23 13:20:23.560','2017-08-23 21:20:23.000')
insert into Orders values ('Texas',23,'2017-08-23 16:20:23.560','2017-08-23 20:00:23.000')
insert into Orders values ('Texas',23,'2017-08-23 18:20:23.560','2017-08-23 20:00:23.000')
insert into Orders values ('Texas',23,'2017-08-22 12:20:23.560','2017-08-22 14:00:23.000')
insert into Orders values ('Texas',23,'2017-08-22 13:20:23.560','2017-08-22 21:20:23.000')
insert into Orders values ('Texas',23,'2017-08-22 16:20:23.560','2017-08-22 20:00:23.000')
insert into Orders values ('Texas',23,'2017-08-22 19:20:23.560','2017-08-22 20:00:23.000')
]2
The requirement is to get latest datetime from the 'orderedDateTime' column and latest datetime from 'ThresholdDateTime' column which should return a record for each day as mentioned in the output image.
I already have a solution for this, but seeking better answers than mine , as i think my query is having performance issues
select city,orderid, max(OrderedDateTime) as MaxOrderedDateTime ,max(ThresholdDatetime) as MaxThresholdTime
,day(ThresholdDatetime) as [UniqueDay]
from dbo.Orders
where OrderedDateTime<=ThresholdDatetime
and convert(date,OrderedDateTime)=convert(date,ThresholdDatetime)
group by city,orderid,day(ThresholdDatetime)
Try coding like this:
SELECT
o.city,
o.orderid,
MaxOrderedDateTime = MAX(o.OrderedDateTime),
MaxThresholdTime = MAX(o.ThresholdDatetime)
FROM
#Orders o
GROUP BY
o.city,
o.orderid,
CAST(o.OrderedDateTime AS DATE);

how can update column of table by subtracting two columns of other table

create table product
(productid varchar(10) primary key,
productname varhchar(10),
totalquantity number(10),
reorderlevel number(10),
remainingquatity number(10) );
1. produtid productname totalquantity reorderlevel remainingquantity
0001 abc 100 0 0
0002 xyz 80 0 0
create table orders
(orderno varchar(10),
productid(10) references product(productid),
quantityordered number(10));
now my problem is i need to autoupdate the remainingquantity and reorderlevel in product table whenever order is placed i.e remainingquantity=totalquantity-quantityorded and reorderlevel=remainingquantity-quantityordered
i tried the trigger but it is not working please help me out and if there is any other concept than triggers which can used to do this process please mention it
This trigger should work
create or replace trigger product_update
BEFORE insert on orders
for each row
begin
UPDATE PRODUCT
SET remainingquantity = totalquantity - :new.quantityordered,
reorderlevel = remainingquantity - :new.quantityordered
WHERE PRODUCT_ID = :new.PRODUCT_ID;
end;​
Or you can normalize your tables (rewrited for Oracle 11g):
CREATE TABLE product(
id NUMBER(15,0) NOT NULL CONSTRAINT pk_product PRIMARY KEY,
name VARCHAR2(100),
totalquantity NUMBER(15,0)
)/
CREATE TABLE orders(
id NUMBER(15,0) NOT NULL CONSTRAINT pk_orders PRIMARY KEY,
orderno VARCHAR2(100),
quantityordered NUMBER(15,0),
productid NUMBER(15,0) CONSTRAINT fk_orders_product_id REFERENCES product(id)
)/
And use join in query
select Q.id, Q.name,
Q.totalquantity - Q.orderdquantity as remainingquantity,
Q.totalquantity - 2*Q.orderdquantity as reorderlevel
from
(select p.id, p.name, p.totalquantity,
coalesce(sum(o.quantityordered) ,0) as orderdquantity
from product p
left join orders o on o.productid = p.id
group by p.id, p.name, p.totalquantity) Q
Data for tests:
insert into product(id, name, totalquantity) values(1, 'apple', 100)/
insert into product(id, name, totalquantity) values(2, 'tomato', 100)/
insert into product(id, name, totalquantity) values(3, 'carrot', 100)/
insert into orders(id, orderno, quantityordered, productid) values(1, '№1', 10, 1)/
insert into orders(id, orderno, quantityordered, productid) values(2, '№2', 3, 1)/
insert into orders(id, orderno, quantityordered, productid) values(3, '№3', 23, 2)/
Results:
id name remainingquantity reorderlevel
1 apple 87 74
2 tomato 77 54
3 carrot 100 100
Proof SQLFiddle

SQL Stored procedure to obtain top customers

I'm trying to create a stored procedure that goes through a "SALES" table and returns the best two customers of a pharmacy (the two customers who have spent more money).
Here's some code:
Table creation:
create table Customer (
Id_customer int identity(1,1) Primary Key,
Name varchar(30),
Address varchar(30),
DOB datetime,
ID_number int not null check (ID_number > 0),
Contributor int not null check (Contributor > 0),
Customer_number int not null check (Customer_number > 0)
)
create table Sale (
Id_sale int identity(1,1) Primary Key,
Id_customer int not null references Customer(Id_customer),
Sale_date datetime,
total_without_tax money,
total_with_tax money
)
Well, I don't know if this is useful but I have a function that returns the total amount spent by a customer as long as I provide the customer's ID.
Here it is:
CREATE FUNCTION [dbo].[fGetTotalSpent]
(
#Id_customer int
)
RETURNS money
AS
BEGIN
declare #total money
set #total = (select sum(total_with_tax) as 'Total Spent' from Sale where Id_customer=#Id_customer)
return #total
END
Can someone help me get the two top customers?
Thanks
Chiapa
PS: Here's some data to insert so you can test it better:
insert into customer values ('Jack', 'Big street', '1975.02.01', 123456789, 123456789, 2234567891)
insert into customer values ('Jim', 'Little street', '1985.02.01', 223456789, 223456789, 2234567891)
insert into customer values ('John', 'Large street', '1977.02.01', 323456789, 323456789, 3234567891)
insert into customer values ('Jenny', 'Huge street', '1979.02.01', 423456789, 423456789, 4234567891)
insert into sale values (1, '2013.04.30', null, 20)
insert into sale values (2, '2013.05.22', null, 10)
insert into sale values (3, '2013.03.29', null, 30)
insert into sale values (1, '2013.05.19', null, 34)
insert into sale values (1, '2013.06.04', null, 21)
insert into sale values (2, '2013.06.01', null, 10)
insert into sale values (2, '2013.05.08', null, 26)
You can do this with a single query without any special functions:
select top 2 c.id_customer, c.name, sum(s.total_with_tax)
from customer c
join sale s on c.id_customer = s.id_customer
group by c.id_customer, c.name
order by sum(s.total_with_tax) desc
This joins onto a CTE with the top customers.
Remove the WITH TIES option if you want exactly 2 and don't want to include customers tied with the same spend.
WITH Top2
AS (SELECT TOP 2 WITH TIES Id_customer,
SUM(total_with_tax) AS total_with_tax
FROM Sale
GROUP BY Id_customer
ORDER BY SUM(total_with_tax) DESC)
SELECT *
FROM Customer C
JOIN Top2 T
ON C.Id_customer = T.Id_customer
I'm not really into SQL Server dialect, but this one will give you best customers in descending order along with money they spent:
select Id_customer, total_with_tax from
(select Id_customer, sum(total_with_tax) total_with_tax from Sale group by Id_customer)
order by total_with_tax desc