List customers who sold most in mssql - sql-server

I'm new to sql.
I have to select top 3 companies who have the highest sells
Company Table:
CompanyId, Compnayname,etc
Orders Table:
OrderId, companyId,price,etc
select top 3 companyname , (select sum(price) from ordes) as Maximum from company order by Maximum Desc?
I think i need to join these but i cant find a way around it

Join these tables, group by company's name and order by their total sales:
select top 3 c.Companyname, sum(o.price) as TotalSales
from Orders o
inner join Company c on c.CompanyId = o.companyid
group by c.Companyname
order by TotalSales desc

Related

SELECT statement with sub-query

Instructions:
Business case: The accounting department would like a reporting of the top ten vendors with their last invoice date and average invoice amount.
Write a SELECT statement that returns three columns:
VendorName (from the Vendors table)
LatestInv (summary function that returns the last entry from InvoiceDate)
AverageInv: (summary function that returns the average from InvoiceTotal)
Hint: you will need to join two tables before joining to the derived table (the subquery)
Subquery portion: SELECT statement that returns the top ten VendorID and AverageInv (same name and function as described in the outer query). Group the results by the appropriate column and sort the results by AverageInv from largest to smallest. Correlate the subquery as BestVendors and join it to the correct table (where both share a key field).
Group the outer query by the appropriate column and sort the results by LatestInv
most recent to oldest
My code
SELECT VendorName, MAX(InvoiceDate) AS LatestInv, AVG(InvoiceTotal) AS AverageInv
FROM Vendors v JOIN
(SELECT TOP 10 VendorID, AVG(InvoiceTotal) AS AverageInv
FROM Invoices
GROUP BY VendorID
ORDER BY AverageInv DESC) AS BestVendors
ON v.VendorID = BestVendors.VendorID
GROUP BY VendorName
ORDER BY LatestInv
MAX(InvoiceDate) has a red line under it as well as AVG(InvoiceTotal) because they are from the Invoices table. Not the Vendors. However if I use FROM Invoices in the outer query then VendorName won't be recognized? How do I fix this and get the result set that this question is looking for?
Also these pics show some sample data from the Invoices and Vendors Table
Try this:
SELECT VendorName, BestVendors.LatestInv, BestVendors.AverageInv
FROM Vendors v
INNER JOIN
(
SELECT TOP 10 VendorID
,AVG(InvoiceTotal) AS AverageInv
,MAX(InvoiceDate) AS LatestInv
FROM Invoices
GROUP BY VendorID
ORDER BY AverageInv DESC
) AS BestVendors
ON v.VendorID = BestVendors.VendorID
ORDER BY LatestInv DESC

Selecting count of exist rows in other table and join it to our SQL server table

I have two tables in SQL server. first one is table of customers info and second includes all purchases,
At first Table i have id of our customers, and the purchases table although has the id of who bought that product. so how can i select all customers table that include how many time they purchased products?
i tried this
SELECT TOP 2000 COUNT(tblpurchase.id) as id2,tblcustomers.* From tblpurchase
right join on tblpurchase.id=tblcustomers.id
but didn't word. how can i solve this?
Use OUTER APPLY
SELECT TOP 2000 tblcustomers.* ,M.CustomerCount
From tblcustomers
OUTER APPLY(
SELECT COUNT(*) as CustomerCount
from tblpurchase
WHERE tblpurchase.CustomerIDColumn = tblcustomers.id
)M
Here tblpurchase.CustomerIDColumn use actual name of customerID column
Also you can with LEFT JOIN
SELECT TOP 2000
C.*,
P.CustomerCount
From
tblcustomers C LEFT JOIN
(
SELECT
TP.CustomerId,
COUNT(*) as CustomerCount
FROM
tblpurchase TP
GROUP BY
TP.CustomerId
) P ON C.Id = P.CustomerId

Selecting Top Seller from Dealers Table with count of sales

First off I have Agents and each Agent can have dealer(s). I have an agent table containing all of my agents. I have a contracts table where all of the sales are listed. And I have a dealer table that attaches all of the dealers to agents.
SELECT a.agent_name, COUNT(distinct c.dealer_number) as '# of Selling Dealers'
FROM agents a
inner join contracts c on c.agent_number = a.agent_number
inner join dealers d on d.agent_number = a.agent_number
group by agent_name
For example this query if I ran it right now would return
Agent Name # of selling Dealers
Agent #1 6
What I now need to figure out is who is the top seller and how much they sold. This info would be in the contracts table.
So as in the example Agent #1 has 6 dealers who have made sales. Lets pretend Dealer #5 of that list has the most sales.
So it should return as follows:
Agent Name # of selling Dealers Top Dealer Volume
Agent #1 6 Dealer #5 24
I would like to return the dealer_name of the top seller and how many sales they got (also in the contracts table).
Additional Info
Each line in the contracts table counts as a sale. It will have a dealer_name, dealer_number and agent_name, agent_number
agents table has agent_name, agent_number
dealers table has dealer_name, dealer_number, agent_number
contracts table has agent_number, dealer_number
try
SELECT
m.agent_name,
max_dealer_contract_sales,
dealer_name
FROM
(SELECT
agent_name,
MAX(dealer_contract_sales) AS max_dealer_contract_sales
FROM
(SELECT
agent_name,
dealer_name,
COUNT(dealer_name) AS dealer_contract_sales
FROM
contracts
GROUP BY
agent_name,
dealer_name) c
GROUP BY
agent_name) m INNER JOIN
(SELECT
agent_name,
dealer_name,
COUNT(dealer_name) AS dealer_contract_sales
FROM
contracts
GROUP BY
agent_name,
dealer_name) c ON
m.agent_name = c.agent_name AND
max_dealer_contract_sales = dealer_contract_sales
;with AgentPerformance as
(
SELECT agent_number, count(distinct c.dealer_number) as SellingDealers
FROM contracts
GROUP BY agent_number,
), DealerPerformance as
(
SELECT agent_number, dealer_number, count(*) DealerSalesCnt
FROM contracts
GROUP BY agent_number, dealer_number,
), TopDealersTmp as
(
SELECT agent_number, dealer_number, DealerSalesCnt,
row_number() over (partition by agent_number order by DealerSalesCnt desc) rn
FROM DealerPerformance
), TopDealers as
(
SELECT agent_number, dealer_number, DealerSalesCnt
FROM TopDealersTmp
WHERE rn = 1
)
SELECT a.agent_name, ap.SellingDealers, d.dealer_name, td.DealerSalesCnt
FROM AgentPerformance ap
join agents a
on ap.agent_number = a.agent_number
join TopDealers td
on ap.agent_number = td.agent_number
join dealers d
on d.dealer_number = td.dealer_number
In AgentPerformance I calculate amount of selling dealers.
In DealerPerformance I calculate how many sales every dealer has (to choose the best one later).
In TopDealersTmp I re-number dealers according to performance starting from top performers for each agent.
In TopDealers I select only top performers.
In final select I pull names by numbers and do output.

Need help creating a query for a non-normalized database

I've never worked with a non-normalized database before, so I'll try and explain my problem as best I can. So I have two tables:
The customers table holds all the customers information, and the orders table holds all the orders that they have placed. I haven't listed all the fields in the tables, just the ones that I need. The customer number in both tables is not the primary key, but I'm inner joining on them anyway. So the problem I'm having is that I don't know how to make a query that:
Selects all the customers with their first name, last name, and email, and also show the most recent orderdate, most recent total, and most recent ordertype. I know that I have to use a max() aggregate for the date, but that's as far as I got. Please help a noob out.
You can try:
SELECT FirstName,
LastName,
Email,
OrderDate,
OrderTotal,
OrderType
FROM Customers AS C
INNER JOIN Order AS O
ON O.CustomerNumber = C.CustomerNumber AND
O.OrderDate = (
SELECT MAX (O1.OrderDate)
FROM Order AS O1
WHERE O1.CustomerNumber = C.CustomerNumber)
)
assuming that Orders.OrderDate is unique for each CustomerNumber, does this work for you? if a single CustomerNumber has more than one entry in Order for OrderDate, you'll get each of those rows.
select c.FirstName, c.LastName, c.Email, o.OrderDate, o.OrderTotal, o.OrderType
from Customers c
join
(select CusomterNumber, max(OrderDate) as MostRecentOrderDate
from Orders
group by CustomerNumber
) mro on mro.CustomerNumber=s.CustomerNumber
join Orders o on o.OrderDate=mro.MostRecentOrdeDate and
o.CustomerNumber=mro.CustomerNumber
Try this:
SELECT
Customers.*, Orders.*
FROM
Customers
JOIN
(SELECT
Customer_Number,
MAX(Order_Date) OrderDate
FROM
Orders
GROUP BY
Customer_Number
) as Ord ON Customers.Customer_Number = Ord.Customer_Number
JOIN Order ON Orders.Customer_Number = Ord.Customer_Number
If you are doing this with SQL Server use the query designer and basically all you want to do is do a join since you have two keys that are the same one in Customer Table ->Customer Join on Order->Customer alias the Customer table as C and Orders table as O
so for example
SELECT Customer.*, Orders.*
From Customer c, Orders O INNER JOIN O where C.Customer Number = O.Customer Number
This should be enough to get you started.. if you don't want all the fields then fully qualify the names for example
SELECT C.FirstName, C.LastName, O.OrderDate, O.OrderType FROM Customer C, Orders O
WHERE C.Customer NUmber = O.Customer Number //this is another way of doing a Join when working with the where Clause.

Using SELECT TOP from one column, then sorting on a different column

I'm using SQL Server 2005, and I want to query for the vendors generating the most revenue, sorted by the vendor's name. Below is the query I have tried. The inner subquery gets the 15 largest vendors sorted by revenue, and I try to order those results by the vendor name.
SELECT Revenue, VendorName
FROM (
SELECT TOP 15
SUM(po.POTotal) AS Revenue
, Vendors.VendorName AS VendorName
FROM PurchaseOrders po
INNER JOIN Vendors ON po.Vendor_ID = Vendors.Vendor_ID
WHERE ...
GROUP BY Vendors.VendorName
ORDER BY Revenue DESC
)
ORDER BY VendorName ASC
But this gives me an error message:
Msg 156, Level 15, State 1, Line 14
Incorrect syntax near the keyword 'ORDER'.
Is there another way to do this? I think this might be possible with a view, but I'd prefer not to do it that way.
I apologize if this is a duplicate, I don't even know what to search for to see if this has already been asked.
Add an alias for the subquery:
SELECT Revenue, VendorName
FROM (SELECT TOP 15
SUM(po.POTotal) AS Revenue,
v.VendorName AS VendorName
FROM PurchaseOrders po
JOIN Vendors v
ON po.Vendor_ID = v.Vendor_ID
WHERE ...
GROUP BY v.VendorName
ORDER BY Revenue DESC) Z
ORDER BY VendorName ASC
You need to give your derived table an alias:
...
ORDER BY Revenue DESC
) AS DerivedTable
ORDER BY VendorName;
I believe you can do this with a CTE:
WITH revenue (Revenue, VendorName)
AS
(SELECT TOP 15 SUM(po.POTotal) AS Revenue, Vendors.VendorName AS VendorName
FROM PurchaseOrders po
INNER JOIN Vendors
ON po.Vendor_ID = Vendors.Vendor_ID
WHERE ...
GROUP BY Vendors.VendorName
ORDER BY Revenue DESC)
SELECT Revenue, VendorName
FROM revenue
ORDER BY VendorName ASC
You can also do this without a sub-query if you like --
SELECT sum(po.POTotal) as Revenue, vendors.VendorName
FROM PurchaseOrders po INNER JOIN Vendors ON po.Vendor_ID = Vendors.Vendor_ID
WHERE ...
GROUP BY Vendors.VendorName
ORDER BY sum(po.POTotal) DESC, VendorName ASC
Try that and see if it works - we do the same sort of thing here and this was our solution...
Sorry, forgot the TOP 15 in the query above - it needs to go just befor the sum() aggregate function.

Resources