Top 10 by Customer - Total - sql

I'm having some issues....how do I get the following code fixed to return the table below as a sum of customers? I want a total of customer quantities by customer, and then a top 10 list. So all of the Yellow Rose should be added together and then counted as one entry, instead of all of their shipments showing up individually.
select top 10 T1.Quantity, T1.CustName
from
(
select
SUM(Tkscale.Qty)Quantity,
Slcust.Name CustName
from Tkscale with (nolock)
left outer join Slcust with (nolock) on Tkscale.CustomerID = Slcust.CustomerID
group by Tkscale.CustomerID, Tkscale.Qty, Slcust.Name
) T1
order by T1.CustName desc, T1.Quantity desc

try to remove in grouping 'Tkscale.Qty'

Remove the Tkscale.Qty from the GROUP BY clause in your inner query. I also think that you want top 10 largest customers by quantity, not by their names:
select top 10 T1.Quantity, T1.CustName
from
(
select
SUM(Tkscale.Qty)Quantity,
Slcust.Name CustName
from Tkscale with (nolock)
left outer join Slcust with (nolock) on Tkscale.CustomerID = Slcust.CustomerID
group by Slcust.Name
) T1
order by T1.Quantity desc, T1.CustName desc
^ change the sequence of the ORDER BY clause

Related

Not getting the result that I need by using ROW_NUMBER()

I'm using advantureworks2017 and what I'm trying to get is the top 2 selling products by year,, what I have so far is this but it's showing me only the top 2 rows which is not what I need, I need the top 2 products in each year.
SELECT TOP (2) ROW_NUMBER() OVER (ORDER BY sum(linetotal) DESC) ,
ProductID,
year(h.OrderDate) 'OrderYear'
from Sales.SalesOrderDetail so
left outer join Sales.SalesOrderHeader h
on so.SalesOrderID = h.SalesOrderID
group by year(h.OrderDate), ProductID
Try to add row_number in the subquery and then use that rank <= 2 in the outer query to select top 2
select
ProductID,
OrderYear
from
(
SELECT
ProductID,
year(h.OrderDate) 'OrderYear',
ROW_NUMBER() OVER (ORDER BY sum(linetotal) DESC) as rnk
from Sales.SalesOrderDetail so
left outer join Sales.SalesOrderHeader h
on so.SalesOrderID = h.SalesOrderID
group by year(h.OrderDate), ProductID
) val
where rnk <= 2
When you ORDER your ROW_NUMBER by sum(linetotal) it's goning to fail if you have multiple sum(linetotal) which are equal.
I prefer to do it that way:
Declare table(number of columns = number of your query results columns + 1)
fill first column in declared table with identity(1,1) and next insert query results into the rest columns.

Select Sold and unsold product from same table in SQL Server for last month

I have Database table and trying to write query to find sold and not sold product list from one table.
Table is Below
Expecting Result
How do i get this result? i am using CTE to create Tamp table and with all services and then do left join but it dose give me only product sold in Feb, but i want all product with no sell too.
You can cross join the products and the dates, and then bring the table with a left join:
select
p.product,
t.quantity_sold,
d.yr,
d.mn
from (select distinct product from mytable) p
cross join (select distinct yr, mn from mytable) d
left join mytable t
on t.product = p.product
and t.yr = d.yr
and t.mn = d.mn
This puts nulls for rows with no sale - that's presumably a numeric column so you generally don't want to write a string like 'Not Sold' into it.
If there is a possibility of duplicate (product, yr, mn), you might want to use outer aggregation:
select
p.product,
sum(t.quantity_sold) quantity_sold,
d.yr,
d.mn
from (select distinct product from mytable) p
cross join (select distinct yr, mn from mytable) d
left join mytable t
on t.product = p.product
and t.yr = d.yr
and t.mn = d.mn
group by p.product, d.yr, d.mn

Find average revenue by each subcategory of top 5 categories in terms of quantity sold in vba sql

I have two data set prod_cat_info and Transactions with two common fields for product category and sub category. I am trying to get average revenue by each subcategory of top 5 category in terms of quantity sold. I tried it from below query in which where clause is not working.
SELECT prod_cat_info.prod_subcat, AVG(Transactions.total_amt)
FROM Transactions INNER JOIN
prod_cat_info
ON Transactions.prod_cat_code = prod_cat_info.prod_cat_code AND
Transactions.prod_subcat_code = prod_cat_info.prod_sub_cat_code
GROUP BY prod_cat_info.prod_subcat
WHERE Transactions.prod_cat_code IN (
SELECT TOP 5 Transactions.prod_cat_code
FROM Transactions
GROUP BY Transactions.prod_cat_code
ORDER BY SUM(Transactions.Qty) DESC
)
GROUP BY prod_cat_info.prod_subcat
You don't need a subquery at all. Just use TOP and ORDER BY:
SELECT TOP (5) pci.prod_subcat, AVG(t.total_amt)
FROM Transactions t INNER JOIN
prod_cat_info pci
ON t.prod_cat_code = pci.prod_cat_code AND
t.prod_subcat_code = pci.prod_sub_cat_code
GROUP BY pci.prod_subcat
ORDER BY SUM(t.qty DESC);
EDIT:
In MS Access and for the clarified question:
SELECT pci.prod_cat_code, pci.prod_subcat, AVG(t.total_amt)
FROM Transactions as t INNER JOIN
prod_cat_info as pci
ON t.prod_cat_code = pci.prod_cat_code AND
t.prod_subcat_code = pci.prod_sub_cat_code
WHERE pci.prod_cat_code IN (
SELECT TOP 5 t.prod_cat_code
FROM Transactions as t
GROUP BY t.prod_cat_code
ORDER BY t.qty DESC
)
GROUP BY pci.prod_cat_code, pci.prod_subcat;

Get max value from another query

I have problems with some query. I need to get max value and product_name from that query:
select
products.product_name,
sum(product_invoice.product_amount) as total_amount
from
product_invoice
inner join
products on product_invoice.product_id = products.product_id
inner join
invoices on product_invoice.invoice_id = invoices.invoice_id
where
month(invoices.invoice_date) = 2
group by
products.product_name
This query returns a result like this:
product_name | total_amount
--------------+--------------
chairs | 70
ladders | 500
tables | 150
How to get from this: ladders 500?
Select product_name,max(total_amount) from(
select
products.product_name,
sum(product_invoice.product_amount) as total_amount
from product_invoice
inner join products
on product_invoice.product_id = products.product_id
inner join invoices
on product_invoice.invoice_id = invoices.invoice_id
where month(invoices.invoice_date) = 2
group by products.product_name
) outputTable
You can use order by and fetch first 1 row only:
select p.product_name,
sum(pi.product_amount) as total_amount
from product_invoice pi inner join
products p
on pi.product_id = p.product_id inner join
invoices i
on pi.invoice_id = i.invoice_id
where month(i.invoice_date) = 2 -- shouldn't you have the year here too?
group by p.product_name
order by total_amount
fetch first 1 row only;
Not all databases support the ANSI-standard fetch first clause. You may need to use limit, select top, or some other construct.
Note that I have also introduced table aliases -- they make the query easier to write and to read. Also, if you are selecting the month, shouldn't you also be selecting the year?
In older versions of SQL Server, you would use select top 1:
select top (1) p.product_name,
sum(pi.product_amount) as total_amount
from product_invoice pi inner join
products p
on pi.product_id = p.product_id inner join
invoices i
on pi.invoice_id = i.invoice_id
where month(i.invoice_date) = 2 -- shouldn't you have the year here too?
group by p.product_name
order by total_amount;
To get all rows with the top amount, use SELECT TOP (1) WITH TIES . . ..
If you are using SQL Server, then TOP can offer a solution:
SELECT TOP 1
p.product_name,
SUM(pi.product_amount) AS total_amount
FROM product_invoice pi
INNER JOIN products p
ON pi.product_id = p.product_id
INNER JOIN invoices i
ON pi.invoice_id = i.invoice_id
WHERE
MONTH(i.invoice_date) = 2
GROUP BY
p.product_name
ORDER BY
SUM(pi.product_amount) DESC;
Note: If there could be more than one product tied for the top amount, and you want all ties, then use TOP 1 WITH TIES, e.g.
SELECT TOP 1 WITH TIES
... (the same query I have above)

Hide column in sql query output

SELECT
MProduct.ProductCode, MProduct.ProductName, COUNT(*) AS Ranges
FROM
TProblem
FULL OUTER JOIN
MProduct ON TProblem.ProductCode = MProduct.ProductCode
GROUP BY
MProduct.ProductCode, MProduct.ProductName
ORDER BY
Ranges DESC
This is my query but I want to hide the Ranges column from output
To maintain the order of your results, just move the count from your select to the order by:
SELECT
MProduct.ProductCode, MProduct.ProductName
FROM
TProblem
FULL OUTER JOIN
MProduct ON TProblem.ProductCode = MProduct.ProductCode
GROUP BY
MProduct.ProductCode, MProduct.ProductName
ORDER BY
count(*) DESC
I understand where #marc_s is coming from. It looks like you are trying to get a list of DISTINCT rows
SELECT ProductCode, ProductName
FROM
(
SELECT TOP 100 PERCENT
MProduct.ProductCode, MProduct.ProductName, COUNT(*) AS Ranges
FROM
TProblem
FULL OUTER JOIN
MProduct ON TProblem.ProductCode = MProduct.ProductCode
GROUP BY
MProduct.ProductCode, MProduct.ProductName
ORDER BY
Ranges DESC
) AS DATA
Or alternatively
SELECT DISTINCT
MProduct.ProductCode, MProduct.ProductName
FROM
TProblem
FULL OUTER JOIN
MProduct ON TProblem.ProductCode = MProduct.ProductCode
MProduct.ProductCode, MProduct.ProductName