Reputation: 4416
The following SQL query that displays products sold sorted by cost and number of orders have to be sorted in a partitioned manner. Namely, products with the cost of under $100 should go first and then everything else that is > $100 should follow it. Adding HAVING TS.TotalSold < 100
to the query would accomplish this for the first partition, but would filter out other products. The operation should be atomic, so that this query can be executed only once.
NOTE: cost by which the query has to be partitioned is calculated as a max of two cost columns, which makes things a bit more complicated (the proposed solutions of CASE WHEN won't work as HighestCost is not a column)
SELECT PS.ProductName, TS.TotalSold,
((PS.Cost1 + PS.Cost2 + ABS(PS.Cost1-PS.Cost2)) / 2) as HighestCost
FROM Products as PS
CROSS APPLY
(SELECT
(SELECT COUNT(OrderId)
FROM Orders as OS
WHERE OS.ProductId=PS.ProductId)
as TotalSold) TS
ORDER BY HighestCost ASC, TS.TotalSold
EDIT: modified the query to include calculated cost by which the query has to be partitioned.
Upvotes: 1
Views: 293
Reputation: 3218
I don't know which dbms you are using but in mine I would use a calculated column to assign a partitionId, and sort by that. Something like this:
SELECT PS.ProductName, TS.TotalSold,
(if cost < 100 then 1 else 2 endif) as partition
FROM Products as PS
CROSS APPLY
(SELECT
(SELECT COUNT(OrderId)
FROM Orders as OS
WHERE OS.ProductId=PS.ProductId)
as TotalSold) TS
ORDER BY partition, PS.Cost ASC, TS.TotalSold
Upvotes: 1
Reputation: 107716
SELECT *
FROM
(
SELECT PS.ProductName, TS.TotalSold,
((PS.Cost1 + PS.Cost2 + ABS(PS.Cost1-PS.Cost2)) / 2) as HighestCost
FROM Products as PS
CROSS APPLY
(SELECT COUNT(OrderId) as TotalSold
FROM Orders as OS
WHERE OS.ProductId=PS.ProductId) TS
) SQ
ORDER BY CASE WHEN HighestCost > 100 THEN 1 END ASC, TotalSold
original below
SELECT PS.ProductName, TS.TotalSold
FROM Products as PS
CROSS APPLY
(SELECT COUNT(OrderId) as TotalSold
FROM Orders as OS
WHERE OS.ProductId=PS.ProductId) TS
ORDER BY
CASE WHEN TS.TotalSold > 100 THEN 1 END, PS.Cost ASC, TS.TotalSold
You may notice I removed a subquery level since it was extraneous.
Upvotes: 1