I'm trying to do this task:
Find total amount of all orders for each customer, sort customers by
the value from maximum amount to minimum and show customers from 40 to
50 position in the result. Only one query.
I'm training on Northwind sample database. My query:
;WITH MyCte AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY SUM(OD.UnitPrice*OD.Quantity*(1-OD.Discount)) DESC) Number
, O.CustomerID
, SUM(OD.UnitPrice*OD.Quantity*(1-OD.Discount)) TotalAmount
FROM [Order Details] OD
RIGHT JOIN Orders O ON OD.OrderID = O.OrderID
GROUP BY CustomerID
ORDER BY TotalAmount DESC
)
SELECT
Number
, CustomerID
, TotalAmount
FROM MyCte
WHERE Number BETWEEN 40 AND 50
But this doesn't work. May someone help me to put "Where" correctly to this query?
;WITH MyCte AS
(
SELECT
ROW_NUMBER() OVER (ORDER BY SUM(OD.UnitPrice*OD.Quantity*(1-OD.Discount)) DESC) Number
, O.CustomerID
, SUM(OD.UnitPrice*OD.Quantity*(1-OD.Discount)) TotalAmount
FROM [Order Details] OD
RIGHT JOIN Orders O ON OD.OrderID = O.OrderID
GROUP BY CustomerID
)
SELECT
Number
, CustomerID
, TotalAmount
FROM MyCte
WHERE Number >= 40 and Number <= 50
Main trouble was in Order By in MyCTE table. This query will work.
Related
Write an SQL command that retrieves last name and first name of all customers and the order numbers of orders they have placed…
CustDetails TABLE: http://prntscr.com/msicdp
OrderDetails TABLE: http://prntscr.com/msichp
I am trying to display list of all users from CustDetails (table), with an additional column, "TotalOrders", that counts how many orders each user have from OrderDetails (table) with COUNT(*), but it seems like I have no idea what am I doing.
I've tried LEFT JOIN paired with COUNT(*) AS [Total Orders] and I am getting all kind of errors whatever I try
SELECT DISTINCT CustDetails.*, OrderDetails.CustRef,COUNT(*) AS [Order_number]
FROM CustDetails
LEFT JOIN OrderDetails ON CustDetails.CustRef = OrderDetails.CustRef
GROUP BY CustDetails.FName
--SELECT CustDetails.CustRef, count(*) AS NUM
-- FROM CustDetails GROUP BY CustRef
You can't put * with GROUP BY. If you are using GROUP BY, all non-aggregated columns should be present in your GROUP BY clause.
You need to write your query like the following.
select c.CustRef,
c.LName,
c.Fname,
sum(case when od.CustRef is null then 0 else 1 end) TotalOrders
from CustDetails c
left join OrderDetails od on od.CustRef =c.CustRef
group by c.CustRef ,c.LName, C.Fname
In case you need all the columns you can try like the following without GROUP BY.
select *,
(select count(*) from OrderDetails od where od.CustRef =c.CustRef) TotalOrders
from CustDetails c
Another way of doing it using PARTITION BY
select * from
(
select c.*,
sum(case when od.CustRef is null then 0 else 1 end) over(partition by c.CustRef) as TotalOrders,
row_number() over (partition by c.CustRef order by (select 1)) rn
from CustDetails c
left join OrderDetails od on od.CustRef =c.CustRef
) t
where rn=1
Hi can you please take a look why my query is not returning distinct record. i want result with following condition OE1='SCHEDCHNG', need only recent records per orderid or ordernum means only one record per ordernum or orderid and also dropdate is null. My query is as below
select DISTINCT TOP 100 OE.ORDERID,OE.ID,OE.ORDERNUM,OE.OE4 from OrderExports OE
inner join (
select ORDERNUM, max(OE4) as MaxDate
from OrderExports
group by ORDERNUM
) tm
on OE.ORDERNUM = tm.ORDERNUM and OE.OE4 = tm.MaxDate
inner join orde_ O on OE.ORDERID = O.ORDERID
WHERE OE1='SCHEDCHNG' AND O.DROPDATE is null
Pretty sparse on details here but I think you are wanting something along these lines.
with SortedResults as
(
select OE.ORDERID
, OE.ID
, OE.ORDERNUM
, OE.OE4
, ROW_NUMBER() over(partition by OE.ORDERID, OE.ORDERNUM order by OE.OE4 desc) as RowNum
from OrderExports OE
inner join
(
select ORDERNUM
, max(OE4) as MaxDate
from OrderExports
group by ORDERNUM
) tm on OE.ORDERNUM = tm.ORDERNUM and OE.OE4 = tm.MaxDate
inner join orde_ O on OE.ORDERID = O.ORDERID
WHERE OE1='SCHEDCHNG'
AND O.DROPDATE is null
)
select ORDERID
, ID
, ORDERNUM
, OE4
from SortedResults
where RowNum = 1
You can try using max and group by as below :
SELECT a.ID, max(a.ORDERID) as OrderID, max(a.ORDERNUM) as OrderNum,MAX(OE.OE4) as OE4 FROM
(
--your query
) a
group by a.ID
I have two tables.
abc(CID(pk), cname,)
order(order_id(pk), CID(fk), number_of_rentals)
I want to determine top 10 customers on the basis of number of movies they rented.
select
orders.cid,orders.no_rentals, abc.name,
rank() over (order by no_rentals desc) "rank"
from abc
inner join orders on orders.CID = abc.CID;
I used this query but it's not universal. How can I use sum function on number_of_rentals with this query?
Select Top 10
orders.cid
, abc.name
, SUM(orders.no_rentals) TotalRentals
, rank() over (order by SUM(orders.no_rentals) desc) [rank]
from abc
inner join orders on orders.CID = abc.CID
Group By orders.cid, abc.name
Order By TotalRentals DESC
This is my first time around here :p
I have SQL Server practice.
Based on the country where Northwind customers reside, show the sum of the 5 highest purchase orders by country. The results should be presented in two columns: country, amount
I tried:
SELECT
vt.ShipCountry, vt.suma
FROM
(SELECT
o.ShipCountry,
SUM( UnitPrice * Quantity * (1-discount)) as suma,
RANK() OVER (PARTITION BY SUM(UnitPrice * Quantity * (1-discount)) ORDER BY shipCountry DESC) AS Rank
FROM
orders o
JOIN
[Order Details] od ON o.OrderID = od.OrderID
GROUP BY
o.ShipCountry) as vt
WHERE
Rank <= 5
GROUP BY
vt.ShipCOUNTRY, vt.suma
but, it retrieves me the sum of all orders per country, only want the top 5 per country
Here's another one, same issue.
SELECT
ShipCountry, rk, amount
FROM
(SELECT
o.ShipCountry,
SUM(UnitPrice * Quantity * (1-discount)) amount,
DENSE_RANK() OVER(PARTITION BY o.ShipCountry ORDER BY SUM(UnitPrice * Quantity * (1-discount)) DESC) AS rk
FROM
Orders o
JOIN
[Order Details] od ON o.OrderID = od.OrderID
GROUP BY
o.shipCountry) AS L
WHERE
rk <= 5;
The two queries have the same behaviour
Try this:
-- first, sum up the total amount of each order
;WITH OrderDetails AS
(
SELECT
o.OrderID,
TotalOrderAmount = SUM(UnitPrice * Quantity * (1 - discount))
FROM
orders o
INNER JOIN
[Order Details] od ON o.OrderID = od.OrderID
GROUP BY
o.OrderID
),
-- secondly, join the "ShipCountry" to the order totals,
-- and define a ROW_NUMBER() for each country, based on
-- total order amount
OrderPerCountry AS
(
SELECT
o.ShipCountry,
od.TotalOrderAmount,
RowNum = ROW_NUMBER() OVER(PARTITION BY o.ShipCountry ORDER BY od.TotalOrderAmount DESC)
FROM
OrderDetails od
INNER JOIN
dbo.Orders o ON o.OrderID = od.OrderID
)
SELECT *
FROM OrderPerCountry
WHERE RowNum <= 5
This should do the trick for you - I hope!
I want to query the highest discount level for each customer, using Rank().
But some of data is missing and I don't know why..
(I used database Northwind)
this is script I have tried..
WITH CTE AS
(SELECT ProductID, CustomerID, Discount,
RANK() over (partition by CustomerID order by Discount desc) as rank
FROM Orders
JOIN [Order Details]
ON Orders.OrderID= [Order Details].OrderID
)
SELECT Distinct ProductID, CustomerID, Discount
FROM CTE
WHERE
Discount>0.1 and
ProductID between 60 and 65 and
rank=1
order by CustomerID
before this process,
I tried this script beforehand
select ProductID, customerID, Discount
from Orders
join [Order Details]
on orders.OrderID = [Order details].OrderID
where
Discount>0.1 and
ProductID between 60 and 65
order by ProductID, CustomerID
go
And I edit manually to get highest discount level for each customer.
I should have about 32 rows (It depends on if I remove repeated data or not)
But when I run first script, I just get 15 rows..
How can I solve this problem? Any helps would be appreciated.
You are calculating RANK() before you apply your filters, which means that some rows that were Rank() = 1 could be eliminated by the filters. Try moving your filters up into the CTE.
;WITH cte
AS (SELECT productid,
customerid,
discount,
Rank()
OVER (
PARTITION BY customerid
ORDER BY discount DESC) AS [rank]
FROM orders
JOIN [order details]
ON orders.orderid = [order details].orderid
WHERE discount > 0.1
AND productid BETWEEN 60 AND 65)
SELECT DISTINCT productid,
customerid,
discount
FROM cte
WHERE [rank] = 1
ORDER BY customerid