SQL List total orders in descending order - sql

SELECT Customer.CID, Count(Order.OrderID) AS [# Orders]
FROM Customer INNER JOIN [Order] ON Customer.CID = Order.CID
Group By Customer.CID DESC;
Im trying to list the total number of orders by customer in descending order. I get a syntax error on the group by clause. Im not sure what the syntax error is.

You're missing your ORDER BY clause. Your query should look like:
SELECT Customer.CID, Count(Order.OrderID) AS [# Orders]
FROM Customer INNER JOIN [Order] ON Customer.CID = Order.CID
GROUP BY Customer.CID
ORDER BY Customer.CID DESC;

You should use order by instead of group by.
So your new query will be,
SELECT Customer.CID, Count(Order.OrderID) AS [# Orders]
FROM Customer INNER JOIN [Order] ON Customer.CID = Order.CID
Order By Customer.CID DESC;
I don't have tables. so please provide your remark.

Related

Adventure Works SQL Server 2014 Enquiry

I am writing a SQL query using the AdventureWorks 2014 database. I want to show which employee has sold for the highest order value.
I tried to write each select statement by itself (see below), but I'd like to be able to combine both queries into one:
select
s.SalesOrderID, s.SalesPersonID, COUNT(sd.SalesOrderID) as count
from
Sales.SalesOrderHeader s, Sales.SalesOrderDetail sd
where
s.SalesOrderID = sd.SalesOrderID
group by
sd.SalesOrderID, s.SalesOrderID, s.SalesPersonID
order by
sd.SalesOrderID
select
sd.SalesOrderID, sd.LineTotal, count (sd.SalesOrderID) as count
from
Sales.SalesOrderDetail sd
group by
sd.SalesOrderID, sd.LineTotal
order by
sd.SalesOrderID
are you looking for something like this:
select top 1
s.SalesPersonID
,sum(sd.LineTotal ) as orderTotal
s.salesorderid
from
Sales.SalesOrderHeader s
inner join Sales.SalesOrderDetail sd
on s.SalesOrderID = sd.SalesOrerID
group by
s.SalesPersonID
s.salesorderid
order by
orderTotal desc
in SQL server you can just ask for a limited number of rows with the top function (this can give you the highest order value when sorted correctly). this can be used with a group by that adds all the line totals together that have the same values in the columns being grouped by.
This is what I would do, to get the total by each Sales Person. Order by the Sum(sd.LineTotal) descending to get the Highest Value.
select s.SalesPersonID ,COUNT(sd.SalesOrderID) as count,sum(sd.LineTotal ) as orderTotal
from Sales.SalesOrderHeader s
Inner Join Sales.SalesOrderDetail sd ON s.SalesOrderID=sd.SalesOrderID
group by s.SalesPersonID
order by 3 Desc
We appreciate your effort. However, there is a simpler way to get your answer.
SELECT
-- TOP 1 //to get highest order total
s.SalesPersonID
,COUNT(sd.SalesOrderID) as Total_Count
,sum(sd.LineTotal) as orderTotal
FROM
Sales.SalesOrderHeader s Inner Join Sales.SalesOrderDetail sd
ON s.SalesOrderID=sd.SalesOrderID
GROUP BY s.SalesPersonID
HAVING s.SalesPersonID IS NOT NULL
ORDER BY sum(sd.LineTotal) desc
What I am doing is, joining SalesOrderHeader with SalesOrderDetail through SalesOrderId and using aggregate functions to get desired result.
Order by is use to get highest value first. Top 1 is use to get only desired output.

SQL TOP 1 Syntax for a nested query

New to SQL Server and I am trying to use top 1 to get the company with the most order in my DB within my code that is already working but I don't know how to use it properly. Only missing syntax I think.
Query #1 is working fine:
SELECT
c.CompanyName, COUNT(DISTINCT OrderID) as Nombre_Commande
FROM
Orders O
INNER JOIN
Customers C ON O.CustomerID = c.CustomerID
GROUP BY
c.CompanyName
What I am trying to do
SELECT TOP (1) *
FROM
(SELECT
c.CompanyName, COUNT(DISTINCT OrderID) AS Nombre_Commande
FROM
Orders O
INNER JOIN
Customers C ON O.CustomerID = c.CustomerID
GROUP BY
c.CompanyName)
You need to give the derived table an alias, and also, specifying top without an order by clause is pretty pointless as rows are returned as a set without any order unless the order is explicitly specified with an order by clause:
SELECT TOP (1) *
FROM (
SELECT c.CompanyName, COUNT(DISTINCT OrderID) as Nombre_Commande
FROM Orders O
INNER JOIN Customers C ON O.CustomerID=c.CustomerID
GROUP by c.CompanyName
) AS YourTable
ORDER BY something_meaningful_maybe_nombre_commande?
How about this?
SELECT TOP 1 c.CompanyName, COUNT(DISTINCT OrderID) as Nombre_Commande
FROM Orders O INNER JOIN
Customers C
ON O.CustomerID = c.CustomerID
GROUP by c.CompanyName
ORDER BY Nombre_Commande DESC;
This assumes that Nombre_Commande is what you want to order by.
By the way, I would be surprised if COUNT(DISTINCT) were really needed for this query. COUNT(*) or COUNT(OrderId) should be sufficient.

Remove duplicates in Left join SQL Server

I am having duplicates in end result. I tried using Distinct as well as group by clause.
Select distinct
Orders.OrderNumber, Tracking.TrackingID,
Orders.BalanceDue, Orders.Approved, Orders.Name, Orders.ShipCity ,
Orders.OrderDate, Orders.country, Orders.Shipping, Orders.CartId
from
orders
left join
Tracking on Orders.OrderNumber = Tracking.ordernum
group by
Orders.OrderNumber, Orders.BalanceDue, Tracking.TrackingID,
Orders.Approved, Orders.Name, Orders.ShipCity,
Orders.OrderDate, Orders.country, Orders.Shipping, Orders.CartId
There are 8166 rows in Orders table and I want only that many columns in end result.
![enter image description here][3]
One way to get one tracking id is to use an aggregation function and remove trackingid from the group by clause:
Select o.OrderNumber, max(t.TrackingID) as TrackingId,
o.BalanceDue, o.Approved, o.Name, o.ShipCity,
o.OrderDate, o.country, o.Shipping, o.CartId
from orders l left join
Tracking t
on o.OrderNumber = t.ordernum
group by o.OrderNumber, o.BalanceDue, o.Approved, o.Name, o.ShipCity,
o.OrderDate, o.country, o.Shipping, o.CartId;

query with subquery with 1 result(max) for each year

I have to make a query where I show for each year wich shipper had the maximum total cost.
My query now show for each year the total cost of each shipper. So in the result i must have a list of the years, for each year the shipper and the total cost.
Thanks in advance.
select year(OrderDate), s.ShipperID, sum(freight)
from orders o
join shippers s on o.ShipVia = s.ShipperID
group by year(OrderDate),s.ShipperID
Select a.FreightYear, a,ShipperID, a.FreightValue
from
(
select year(OrderDate) FreightYear, s.ShipperID, sum(freight) FreightValue
from orders o
join shippers s on o.ShipVia = s.ShipperID
group by year(OrderDate),s.ShipperID
) a
inner join
(
select FreightYear, max(FrieghtTotal) MaxFreight
from
(
select year(OrderDate) FreightYear, s.ShipperID, sum(freight) FreightTotal
from orders o
join shippers s on o.ShipVia = s.ShipperID
group by year(OrderDate),s.ShipperID
) x
group by FreightYear
) max on max.FreightYear = a.FreightYear and max.MaxFreight = a.FreightValue
order by FreightYear
Inner query a is your original query, getting the value of freight by shipper.
Inner query max gets the max value for each year, and then query max is joined to query a, restricting the rows in a to be those with a value for a year = to the max value for the year.
Cheers -
It's marginally shorter if you use windowing functions.
select shippers_ranked.OrderYear as OrderYear,
shippers_ranked.ShipperId as ShipperId,
shippers_ranked.TotalFreight as TotalFreight
from
(
select shippers_freight.*, row_number() over (partition by shippers_freight.OrderYear order by shippers_freight.TotalFreight desc) as Ranking
from
(
select year(OrderDate) as OrderYear,
s.ShipperID as ShipperId,
sum(freight) as TotalFreight
from orders o
inner join shippers s on o.ShipVia = s.ShipperID
group by year(OrderDate), s.ShipperID
) shippers_freight
) shippers_ranked
where shippers_ranked.Ranking = 1
order by shippers_ranked.OrderYear
;
You need to decide what you would like to happen if two shippers have the same TotalFreight for a year - as the code above stands you will get one row (non-deterministically). If you would like one row, I would add ShipperId to the order by in the over() clause so that you always get the same row. If in the same TotalFreight case you would like multiple rows returned, use dense_rank() rather than row_number().

SQL Query for counting number of orders per customer and Total Dollar amount

I have two tables
Order with columns:
OrderID,OrderDate,CID,EmployeeID
And OrderItem with columns:
OrderID,ItemID,Quantity,SalePrice
I need to return the CustomerID(CID), number of orders per customer, and each customers total amount for all orders.
So far I have two separate queries. One gives me the count of customer orders....
SELECT CID, Count(Order.OrderID) AS TotalOrders
FROM [Order]
Where CID = CID
GROUP BY CID
Order BY Count(Order.OrderID) DESC;
And the other gives me the total sales. I'm having trouble combining them...
SELECT CID, Sum(OrderItem.Quantity*OrderItem.SalePrice) AS TotalDollarAmount
FROM OrderItem, [Order]
WHERE OrderItem.OrderID = [Order].OrderID
GROUP BY CID
I'm doing this in Access 2010.
You would use COUNT(DISTINCT ...) in other SQL engines:
SELECT CID,
Count(DISTINCT O.OrderID) AS TotalOrders,
Sum(OI.Quantity*OI.SalePrice) AS TotalDollarAmount
FROM [Order] O
INNER JOIN [OrderItem] OI
ON O.OrderID = OI.OrderID
GROUP BY CID
Order BY Count(DISTINCT O.OrderID) DESC
Which Access unfortunately does not support. Instead you can first get the Order dollar amounts and then join them before figuring the order counts:
SELECT CID,
COUNT(Orders.OrderID) AS TotalOrders,
SUM(OrderAmounts.DollarAmount) AS TotalDollarAmount
FROM [Orders]
INNER JOIN (SELECT OrderID, Sum(Quantity*SalePrice) AS DollarAmount
FROM OrderItems GROUP BY OrderID) AS OrderAmounts
ON Orders.OrderID = OrderAmounts.OrderID
GROUP BY CID
ORDER BY Count(Orders.OrderID) DESC
If you need to include Customers that have orders with no items (unusual but possible), change INNER JOIN to LEFT OUTER JOIN.
Create a query which uses your 2 existing queries as subqueriers, and join the 2 subqueries on CID. Define your ORDER BY in the parent query instead of in a subquery.
SELECT
sub1.CID,
sub1.TotalOrders,
sub2.TotalDollarAmount
FROM
(
SELECT
CID,
Count(Order.OrderID) AS TotalOrders
FROM [Order]
GROUP BY CID
) AS sub1
INNER JOIN
(
SELECT
CID,
Sum(OrderItem.Quantity*OrderItem.SalePrice)
AS TotalDollarAmount
FROM OrderItem INNER JOIN [Order]
ON OrderItem.OrderID = [Order].OrderID
GROUP BY CID
) AS sub2
ON sub1.CID = sub2.CID
ORDER BY sub1.TotalOrders DESC;