I'd like to get the Product ID, Product Name and Cash Sales for the product with the HIGHEST Cash Sales from some data.
I know how to write a query which extracts all records then arranges them in order, with the highest Cash Sales at the top (see below).
Then I can select the record with the highest sales from that query.
But is there a quicker way to write this? i.e a simple query which will only return the record with the highest sales? TIA.
select
es.ClientProductID,
es.ProductName,
ash.price * ash.sales as CashSales
from AggregatedSalesHistory as ash
join v_EnterpriseStructure as es on es.ProductSID = ash.ProductSID
group by
es.ClientProductID,
es.ProductName,
ash.price * ash.sales
order by
ash.price * ash.sales DESC
select
es.ClientProductID,
es.ProductName,
ash.price * ash.sales as CashSales
from AggregatedSalesHistory as ash
join v_EnterpriseStructure as es on es.ProductSID = ash.ProductSID
group by
es.ClientProductID,
es.ProductName,
ash.price * ash.sales
having
max(ash.price * ash.sales)
Above query will give you result with highest sales.
You can use ranking and grouping on your result set to get the first rank (or any other rank) row
select * from (select
row_number() over (partition by es.ClientProductID,es.ProductName order by (ash.price * ash.sales) desc) as salesRank,
es.ClientProductID a,
es.ProductName b,
ash.price * ash.sales as CashSales
from AggregatedSalesHistory as ash
join v_EnterpriseStructure as es on es.ProductSID = ash.ProductSID ) subquery1 where salesRank=1;
Related
For each country, report the movie genre with the highest average ratings, and I am missing only one step that i cant figure it out.
Here's my current code:
SELECT c.code AS c_CODE, menres.genre AS GENRE, AVG(RATE) as AVERAGE_rate,MAX(RATE) AS MAXIMUM_rate, MIN(RATE) AS MINIMUM_rate from movirates
leftJOIN movgenres ON movgenres.movieid = movratings.movieid
left JOIN users ON users.userid = movrates.userid
left JOIN c ON c.code = users.city
LEFT JOIN menres ON movenres.genreid = menres.code
GROUP BY menres.genre , c.code
order by c.code asc, avg(rate) desc, menres.genre desc ;
You can use the ROW_NUMBER window function to assign a unique rank to each of your rows:
partitioned by country code
ordered by descendent average rating
Once you get this ranking, you may want to select all those rows which have the highest average rating (which are the same having the ranking equal to 1).
WITH cte AS (
SELECT c.code AS COUNTRY_CODE,
mg.genre AS GENRE,
AVG(rating) AS AVERAGE_RATING,
MAX(rating) AS MAXIMUM_RATING,
MIN(RATING) AS MINIMUM_RATING
FROM moviesratings r
INNER JOIN moviesgenres g ON g.movieid = r.movieid
INNER JOIN users u ON u.userid = r.userid
INNER JOIN countries c ON c.code = u.country
LEFT JOIN mGenres mg ON mg.code = g.genreid
GROUP BY mg.genre,
c.code
ORDER BY c.code,
AVG(rating) DESC,
mg.genre DESC;
)
SELECT *
FROM (SELECT *,
ROW_NUMBER() OVER(
PARTITION BY COUNTRY_CODE,
ORDER BY AVERAGE_RATING) AS rn
FROM cte) ranked_averages
WHERE rn = 1
Note: The code inside the common table expression is equivalent to yours. If you're willing to share your input tables, I may even suggest an improved query.
You should use window function in this case by using rank() then select the first rank only.
with mov_rates(c.code, genre, average, max, min)
as.
select c.code c_code,
e.genre genre,
avg (rate) avg
max (rate) max
min (rate) min
from movrates a
LEFT join movge.nres b on a.movieid = b.movieid
LEFT join users c on a.userid = c.user
LEFT join countr.ies d on c.code = d.code
left join mGenres e on b.genreid = e.code
group by d.country_code, e.x
),
rategenre (rank, c_code, genre, avgrate, max, min)
as
(
select rank() over (partition by c.c order by avgrates asc) rank,
country code,
genre,
average_r.ating,
maximum_rating,
minimum_.ating
from movrate \\just practicing on something
)
selec.t 2
from genre
where rank = 5
Reference:
OVER Clause
Please an you help me with the code by this query?.
I have two fields: 'Customer' and 'Rate'.
Rate values: (BT5A, BT5B, BT5BR, MT1, MT2, MT3)
Customers: 1000 customers by each Rate.
I would like to make a query that randomly returns 3 customers for each rate in the table, in order to have a sample of customers per rate.
How do I improve this code?
SELECT DISTINCT TOP 3
c.RUTA,c.CONTRATO,c.CODIGOANT,c.CODRUTA,c.NOMBRES,c.DIRECCION,
c.SITUACION,c.TARIFA
FROM CLIENTE AS c
INNER JOIN CUENTA AS CU ON c.CONTRATO=CU.CONTRATO
WHERE c.SITUACION NOT IN ('1','9')
AND c.tarifa='BT5A'
AND CU.MES BETWEEN '201907' AND '202007'
UNION
SELECT DISTINCT TOP 3
c.RUTA,c.CONTRATO,c.CODIGOANT,c.CODRUTA,c.NOMBRES,c.DIRECCION,
c.SITUACION,c.TARIFA
FROM CLIENTE AS c
INNER JOIN CUENTA AS CU ON c.CONTRATO=CU.CONTRATO
WHERE c.SITUACION NOT IN ('1','9')
AND c.tarifa='BT5B'
AND CU.MES BETWEEN '201907' AND '202007'
UNION
SELECT DISTINCT TOP 3
c.RUTA,c.CONTRATO,c.CODIGOANT,c.CODRUTA,c.NOMBRES,c.DIRECCION,
c.SITUACION,c.TARIFA
FROM CLIENTE AS c
INNER JOIN CUENTA AS CU ON c.CONTRATO=CU.CONTRATO
WHERE c.SITUACION NOT IN ('1','9')
AND c.tarifa='BT5BR'
AND CU.MES BETWEEN '201907' AND '202007'
I think you can use ROW_NUMBER() to solve you problem and simplify the query"
SELECT t.*
FROM (SELECT c.RUTA, c.CONTRATO, c.CODIGOANT, c.CODRUTA, c.NOMBRES, c.DIRECCION, c.SITUACION, c.TARIFA,
ROW_NUMBER() OVER (PARTITION BY c.tarifa ORDER BY NEWID()) as seqnum
FROM CLIENTE c INNER JOIN
CUENTA CU
ON c.CONTRATO = CU.CONTRATO
WHERE c.SITUACION NOT IN (1, 9) AND
CU.MES BETWEEN '201907' AND '202007'
) t
WHERE seqnum <= 3;
I doubt you really need SELECT DISTINCT. Also, I changed removed the single quotes from NOT IN. The values look like numbers, so I assume they are numbers. If the values really are strings, then use the single quotes.
EDIT:
Use exists to get avoid possible duplicates:
SELECT t.*
FROM (SELECT c.RUTA, c.CONTRATO, c.CODIGOANT, c.CODRUTA, c.NOMBRES, c.DIRECCION, c.SITUACION, c.TARIFA,
ROW_NUMBER() OVER (PARTITION BY c.tarifa ORDER BY NEWID()) as seqnum
FROM CLIENTE c
WHERE c.SITUACION NOT IN (1, 9) AND
EXISTS (SELECT 1
FROM CUENTA CU
WHERE cu.CONTRATO = c.CONTRATO AND
CU.MES BETWEEN '201907' AND '202007'
)
) t
WHERE seqnum <= 3;
Supposing this is SQL Server:
Don't join. Use IN to get the clients where the contract matches your conditions.
Use NEWID to get random numbers.
Use ROW_NUMBER to rank your rows.
If you want to use TOP, you need TOP WITH TIES and an ORDER BY clause.
The query:
SELECT TOP (3) WITH TIES
*
FROM cliente
WHERE contrato IN
(
SELECT contrato
FROM cuenta
WHERE mes BETWEEN '201907' AND '202007'
)
AND situacion NOT IN (1, 9)
ORDER BY ROW_NUMBER() OVER (PARTITION BY tarifa ORDER BY NEWID());
From my Orders table I'm trying to get per product the vendor with the highest Ratio order and lowest price.
select v.[Vendor_pk], p.[Product_pk],o.[UnitPrice], o.[RatioOrder], o.[TotalPrice]
from [DWH].[ORDERSfact] o
inner join [DWH].[VENDORdim] v
on o.[Vendor_pk]=v.[Vendor_pk]
inner join [DWH].[PRODUCTdim] p
on o.[Product_pk]= p.[Product_pk]
order by 2, 4 desc, 3
How can I do that here?
I'm trying to get per product the vendor with the highest Ratio order and lowest price.
Use row_number():
select vp.*
from (select v.[Vendor_pk], p.[Product_pk],o.[UnitPrice], o.[RatioOrder], o.[TotalPrice],
row_number() over (partition by product_pk order by ratioorder desc, price asc) sa seqnum
from [DWH].[ORDERSfact] o join
[DWH].[VENDORdim] v
on o.[Vendor_pk] = v.[Vendor_pk] join
[DWH].[PRODUCTdim] p
on o.[Product_pk] = p.[Product_pk]
) vp
where seqnum = 1;
I'm having an absolute brain fade
SELECT p.ProductCategory, f.ProductSubCategory, COUNT(*) AS Cnt
FROM Sales f
JOIN Products p ON f.ProductSubCategory = p.ProductSubCategory
GROUP BY p.ProductCategory, f.ProductSubCategory
ORDER BY 1,3 DESC
This shows me the count for each ProductSubCategory, I would like to see only the highest ProductSubCategory per ProductCategory.
I wish to see (I don't care about the Count value)
There are a couple of different ways to do this. One involves joining the results back to themselves and using the max aggregate. But since you are using SQL Server, you can use ROW_NUMBER to achieve the same result:
with cte as (
select p.productcategory, p.ProductSubCategory, COUNT(*) cnt,
ROW_NUMBER() over (partition by p.productcategory order by count(*) desc) rn
from products p
join sales s on p.ProductSubCategory = s.ProductSubCategory
group by p.productcategory, p.ProductSubCategory
)
select *
from cte
where rn = 1
You already got the answer, Please see the following code to. It may help you.
SELECT p.ProductCategory,
f.ProductSubCategory,
COUNT(*) AS Cnt
FROM Sales f
JOIN Products p ON f.ProductSubCategory = p.ProductSubCategory
JOIN (
SELECT p.ProductCategory,
f.ProductSubCategory,
ROW_NUMBER() OVER ( PARTITION BY p.ProductCategory,
f.ProductSubCategory
ORDER BY COUNT(*) DESC) [Row]
FROM Sales f
JOIN Products p ON f.ProductSubCategory = p.ProductSubCategory) Lu
ON P.ProductCategory = Lu.ProductCategory
AND f.ProductSubCategory = Lu.ProductSubCategory
WHERE Lu.Row = 1
GROUP By p.ProductCategory,
f.ProductSubCategory
I am suppose to Write a query that will display the largest number of movies rented by one member and that member's name. Give the output column a meaningful name such as MAXIMUM NUMBER.
This is what I have.
select max(maximum_movies)
from (select count(*)maximum_movies
from mm_member join mm_rental on
mm_rental.member_id = mm_member.member_id
group by first, last);
I got the maximum number but the output should be like this.
First Last Maximum_movies
John Doe 4
But the output is
Maximum_movies
4
Any suggestions?
You could use analytic rank this way. Demo on Fiddle
select memberid,
last,
first,
rental_count
from (
select m.mm_memberid memberid,
m.mm_last last,
m.mm_first first,
count(*) rental_count,
rank() over (order by count(*) desc ) as count_ranking
from mm_member m
inner join mm_rental r on m.mm_memberid=r.mm_memberid
group by m.mm_memberid,
m.mm_last,
m.mm_first
)
where count_ranking=1
Something like this:
WITH CTE_CNT AS (
SELECT first, last, COUNT(*) num
FROM
mm_member
JOIN mm_rental ON mm_rental.member_id = mm_member.member_id
GROUP BY first, last
),
SELECT cnt.first, cnt.last, maxrent.mx
FROM (
SELECT MAX(num) as mx FROM CTE_CNT
) maxrent JOIN CTE_CNT AS cnt ON cnt.num = maxrent.mx
;
use this :
select first,last, maximum_movies
from mm_member join mm_rental on
mm_rental.member_id = mm_member.member_id group by first, last where
maximum_movies = (select max(maximum_movies) from (select count(*)maximum_movies
from mm_member join mm_rental on
mm_rental.member_id = mm_member.member_id group by first, last));
You can do the select in only 1 step. It is not really a MAX you are looking for, just a COUNT of the joined table.
SELECT TOP 1
M.member_id
, M.first
, M.last
, COUNT(R.*) MovieCount
FROM mm_member M
JOIN mm_rental R ON R.member_id = M.member_id
GROUP BY M.member_id, M.first, M.last
ORDER BY MovieCount DESC