SQL Server: getting max purchase value for each individual - sql-server

I have the following query
select
C.Persona, C.Producto, Sum(C.Cantidad * P.Precio) [Total_Purchase]
from
Compras C
join
Precios P on C.Producto = P.Item
group by
C.Producto, C.Persona
which returns the total purchase made by each customer (Persona) for each Product.
How can i get it to bring the Max Total Purchase for each customer and the Product involved?

You can use the MAX() function to do this. You can add it to your select and it will work, even with SUM() being used.
MAX() Examples

Change SUM aggregate to MAX
Or include both
select C.Persona,C.Producto,
Sum(C.Cantidad*P.Precio) [Total_Purchase],
MAX (C.Cantidad*P.Precio) [Total_Purchase
from
Compras C JOIN Precios P ON C.Producto=P.Item
group by C.Producto ,C.Persona

Try this:
select
max(c.[Total_Purchase]), C.Producto ,C.Persona
from
(select
C.Persona, C.Producto, Sum(C.Cantidad*P.Precio) [Total_Purchase]
from
Compras C
join
Precios P on C.Producto = P.Item
group by
C.Producto, C.Persona) c
group by
C.Producto, C.Persona

Related

Subquery in SQL Server using Min, Max, Avg

Task: write a query to generate the total number of invoices, the invoice total for all of the invoices, the smallest invoice amount, the largest invoice amount, and the average of all of the invoices.
My attempt so far:
SELECT
COUNT(DISTINCT Lines.inv_number) as NumberOfInvoices,
SUM(Lines.line_price * Lines.line_units) as TotalSales,
MIN(SELECT SUM(Lines.line_price * Lines.line_units)
FROM dbo.Lines
INNER JOIN dbo.Invoices ON Invoices.inv_number = Lines.inv_number
GROUP BY Invoices.cus_code) as MinimumSale,
MAX(Lines.line_price * Lines.line_units) as LargestSale,
AVG(Lines.line_price * Lines.line_units) as AverageSale
FROM
dbo.Lines
INNER JOIN
dbo.Invoices ON Invoices.inv_number = Lines.inv_number;
I keep getting an error when running. Not sure if I am putting the subquery in the right place.
You can use subquery as below:
SELECT COUNT(A.InvNumber) AS NumberOfInvoices
,A.TotalSales
,MIN(A.TotalSales) AS MinimumSale
,MAX(A.TotalSales) AS LargestSale
,AVG(A.TotalSales) AS AverageSale
FROM (
SELECT
Lines.InvNumber
,SUM(Lines.line_price*Lines.line_units) AS TotalSales
FROM dbo.Lines INNER JOIN dbo.Invoices
ON Invoices.inv_number=Lines.inv_number
GROUP BY Lines.InvNumber
) A
You cannot select minimum on sum as SUM itself returns only one value... Also your syntax itself is not correct

Sum of All Total related to a Vulnerability Name

I have written a query
SELECT Year(outertblissues.opendt) AS Years,
Month(outertblissues.opendt) AS Months,
outertblvulnerability.vulname,
Count(outertblvulnerability.vulid) Vulcount
FROM tbl_apptestdetails AS outertblapptestdetails
INNER JOIN tbl_applicationlist AS outertblapplicationlist
ON outertblapptestdetails.appid = outertblapplicationlist.appid
INNER JOIN tbl_bu AS outertblbu
ON outertblbu.buid = outertblapplicationlist.buid
INNER JOIN tbl_issues AS outertblissues
ON outertblapptestdetails.testdetailid =
outertblissues.testdetailid
AND outertblissues.status NOT IN( '1', '4' )
INNER JOIN tbl_vulnerability AS outertblvulnerability
ON outertblissues.vulid = outertblvulnerability.vulid
GROUP BY Year(outertblissues.opendt),
Month(outertblissues.opendt),
outertblvulnerability.vulname
ORDER BY vulcount DESC
Which gives the following result
Now a want one more column Name as SumOfCount which gives the Sum of all VulCount Related to a particular VulName For example in front of "Additional Issues" The SumOfCount Should be 8 , Similarly for others
If you use Sql Server 2012 or higher you can try instruction Sum() over partition by
SUM(VulCount) OVER(PARTITION BY VulName)

How to use Join on linked servers

I am trying to get results of a customer from two linked servers remotely. i need to sum the points of every cust_id but am having problems with my query
SELECT sum(cust_point) as total
FROM [192.168.23.9].[POSDBV4].[dbo].[loyal_summery_branch] where cust_id='0100015388'
INNER JOIN [192.168.13.4].[POSDBV4].[dbo].[loyal_summery_branch]
ON cust_id.[192.168.23.9].[POSDBV4].[dbo].[loyal_summery_branch]=cust_id.[192.168.13.4].[POSDBV4].[dbo].[loyal_summery_branch];
I think you have your query syntax a little scrambled there. Try this.
SELECT sum(cust_point) as total
FROM [192.168.23.9].[POSDBV4].[dbo].[loyal_summery_branch] A
INNER JOIN [192.168.13.4].[POSDBV4].[dbo].[loyal_summery_branch] B ON A.cust_id=B.cust_id
WHERE cust_id='0100015388'
As you want the sum of cust_point of both of the table. Please find the query below
Select( (SELECT sum(cust_point)
FROM [192.168.23.9].[POSDBV4].[dbo].[loyal_summery_branch] where cust_id='0100015388') +
(SELECT sum(cust_point)
FROM [192.168.13.4].[POSDBV4].[dbo].[loyal_summery_branch] where cust_id='0100015388') ) as total
you can always use a UNION ALL here if you like.. this will allow you select other fields as well if you include a GROUP BY
SELECT SUM(cust_point) AS total
FROM (
SELECT cust_point
FROM [192.168.23.9].[POSDBV4].[dbo].[loyal_summery_branch]
WHERE cust_id = '0100015388'
UNION ALL
SELECT cust_point
FROM [192.168.13.4].[POSDBV4].[dbo].[loyal_summery_branch]
WHERE cust_id = '0100015388'
) t

SQL Inner join show numeric value once

I know my question is not very logical but I have the folowing chalenge:
HeadTab (Uniq_Id N(10)
Name C(30)
Tax N(18,2))
TrsTab (Uniq_Id N(10)
MonthlyDesc C(20)
Amount N(18,2))
What I want is the following select * from headtab inner join Trstab on uniq_id = Uniq_id
the issue is that I want to see the tax field only once per name other related should be 0...(Eventhough I have many lines in the details tab).
Thank you for any help
If you give the query a row number to determine the first row for each Name you can use a case statement to select which value you want for Tax.
SELECT
ht.Uniq_ID,
ht.NAME,
(CASE WHEN ROW_NUMBER() OVER (PARTITION BY ht.NAME ORDER BY ht.Uniq_ID) = 1 THEN ht.Tax ELSE 0 END) Tax,
tt.*
FROM
headtab ht
INNER JOIN Trstab tt ON ht.uniq_id = tt.Uniq_id

Why does this query work only when I use group by?

This query works:
select p.Nombre as Nombre, c.Nombre as Categoria, s.Nombre as Subcategoria FROM Producto as p
inner join Subcategoria as s ON p.IDSubcategoria = s.ID
inner join Categoria as c on s.IDCategoria = c.ID
group by p.Nombre, c.Nombre, s.Nombre
order by p.Nombre
But when I remove the s.Nombre on the group by statement, I get this error:
Msg 8120, Level 16, State 1, Line 1
Column 'Subcategoria.Nombre' is
invalid in the select list because it
is not contained in either an
aggregate function or the GROUP BY
clause.
Can someone explain to me a little bit what the group by function does and why it allows the query to work?
In the interest of learning! Thanks.
When you state group by p.Nombre, you are specifying that there should be exactly 1 row of output for each distinct p.Nombre. Hence, other fields in the select clause must be aggregated (so that if there are multiple rows with the same p.Nombre, they can be 'collapsed' into one value)
By grouping on p.Nombre, c.Nombre, s.Nombre, you are saying that there should be exactly 1 row of output for each distinct tuple. Hence, it works (because the fields displayed are involved in the grouping clause).
If you use GROUP BY clause you can have on SELECT fields:
the fields that you already use in group by section
agregates (min, max, count....) on other fields
One little example:
MyTable
FieldA FieldB
a 1
a 2
b 3
b 5
Query:
select a, b from myTable GroupBy a
A B
a ?
b ?
Which values you want to have in the field B?
a-> 1 or a -> 2 or a -> 3 (1+2)
If the first you need min(a) aggregate function. If you need 2 - max. If 3 - sum().
The group by function collapses those rows that have the same value in the columns specified in the GROUP BY clause to just one row. For any other columns in your SELECT which are not specified in the GROUP BY clause, the SQL engine needs to know what to do with those columns too by way of an aggregation function, e.g. SUM, MAX, AVG, etc. If you don't specify an aggregation function then the engine throws an exception because it doesn't know what to do.
E.g.
select p.Nombre as Nombre, c.Nombre as Categoria, SUM(s.Nombre) as Subcategoria FROM Producto as p
inner join Subcategoria as s ON p.IDSubcategoria = s.ID
inner join Categoria as c on s.IDCategoria = c.ID
group by p.Nombre, c.Nombre
order by p.Nombre
A group-by clause is only required if you use aggregate functions like COUNT or MAX. As a side effect it removes duplicate rows. In your case it is simpler to remove duplicates by adding DISTINCT to the select clause, and removing the group-by clause altogether.
select DISTINCT p.Nombre as Nombre, c.Nombre as Categoria, s.Nombre as Subcategoria FROM Producto as p
inner join Subcategoria as s ON p.IDSubcategoria = s.ID
inner join Categoria as c on s.IDCategoria = c.ID
order by p.Nombre

Resources