Sum function in SQL Server 2008 - sql

I have a table:
PropertyID Amount
--------------------------
1 40
1 20
1 10
2 10
2 90
I would like to achieve :
PropertyId Amount Total_Amount
---------------------------------------
1 40 70
1 20 70
1 10 70
2 10 100
2 90 100
using below query :
SELECT
PropertyID,
SUM(Amount),
SUM(TotalAmount)
FROM
yourTable
WHERE
EndDate IS NULL
GROUP BY
PropertyID
Output:
PropertyId Amount TotalAmount
-------------------------------------
1 70 70
2 100 100
Let me know how can I get my desired output ...

You can do this using window functions:
select PropertyID, Amount,
sum(Amount) over (partition by PropertyId) as TotalAmount
from yourtable;
The window function for sum() does the following. It calculates the sum of amount for groups of rows in the same group. The group is defined by the partition by clause, so rows with the same value of PropertyId are in the same group.

SELECT PropertyID,
Amount,
(select sum(yt.Amount)
from yourTable yt where yt.PropertyID==y.PropertyID and yt.EndDate IS NULL)
as TotalAmount
FROM yourTable y
WHERE y.EndDate IS NULL

Related

Divide each value of a column by the total count of records in a table

A query that is capable of dividing each value of a column by the total number of records in the table
I tried the following query
select ( (p.rank/count(*)) * 100 ) as rankratio from RankTable p;
I see an error and not able to execute the query.
for example
total records is 5 so (1/5)*100 = 20
RankTable
rank rankratio
1 20
2 40
3 60
4 80
5 100
use analytic count(*) over():
select ( (s.rank/s.total_count) * 100 ) as rankratio
from
(
select rank, count(*) over() as total_count
from RankTable p
)s
order by s.rank;

How to get eid from table which is having max number of count in the Mid?

I have a table employee which is having following structure:
Id. Mid Salary
1 20 200
2 20 3000
3 30 200
4 34 4000
5 30 300
6 30 400
1 23 440
1 24 333
2 21 3
I want to get result like:
Id Mid
1 3
You can try below - using top with ties and aggregation
select top 1 with ties id, count(mid) as Mid
from table
group by id
order by count(mid) desc
use top 1
select top 1 id,count(*) as cnt
from table
group by id
order by cnt desc
if you need ties then use with ties
select top 1 with ties id,count(*) as cnt
from table
group by id
order by cnt desc

How to use this in sql -- > max(sum (paid * quantity )) to solve a query

How to get the max value order of each customer ?
select num, max(sum(paid*quantity))
from orders join
pizza
using (order#)
group by customer#;
table
num orderN price
-------- --- -------
1 109 30
1 118 25
3 101 30
3 115 27
4 107 23
5 100 17
5 129 16
output req-
num Pnum price
-------- --- -------
1 109 30
3 101 30
4 107 23
5 100 17
You want to select the record having the highest price in each group of nums.
If your RDBMS supports window functions, that's straight forward with ROW_NUMBER() :
SELECT num, pnum, price
FROM (
SELECT t.*, ROW_NUMBER OVER(PARTITION BY num ORDER BY price DESC) rn
FROM mytable t
) x
WHERE rn = 1
Else, you can take the following approach, that uses a NOT EXISTS condition with a correlated subquery to ensure that the record being joined in the one with the highest price for the current num :
SELECT num, pnum, price
FROM mytable t
WHERE NOT EXISTS (
SELECT 1 FROM mytable t1 WHERE t1.num = t.num AND t1.price > t.price
)

Merge or group rows corresponding to particular column postgresql

I want to group by the resultset further corresponding to the price_type column,
if the data for a product with both price_type variant and parent_product is present, then it must show only the variant one
For example, this data
Product Name PPID QTY PRID PRICE PRICE_TYPE
Shorts 1 10 21 200 variant
Shorts 1 10 21 100 parent_product
Night Suit 1 10 22 200 variant
Night Suit 1 10 22 100 parent_product
Denim 1 10 23 400 parent_product
should come like
Product Name PPID QTY PRID PRICE PRICE_TYPE
Shorts 1 10 21 200 variant
Night Suit 1 10 22 200 variant
Denim 1 10 23 400 parent_product
It seems you want row_number() with conditional ordering:
select *
from (select *, row_number() over (partition by ProductName
order by (case when Price_type = 'variant'
then 0 else 1
end)
) as seq
from table
) t
where seq = 1;
Below is the simple query to get desired result.
select
distinct on(product_name),
t.*
from tab t
order by price_type='variant' desc
You can use a window function:
SELECT * FROM
(
SELECT * ,
RANK() OVER (PARTITION BY product_name ORDER BY priority ) AS rank
FROM (
SELECT *,
CASE
WHEN price_type='variant' THEN 1
ELSE 2
END AS priority
FROM yourtable
) AS X
) AS Y
WHERE rank=1

SUM() data in a column based on another column data

I have a sql table
Project ID Employee ID Total Days
1 100 1
1 100 1
1 100 2
1 100 6
1 200 8
1 200 2
Now i need this table to look like
Project ID Employee ID Total Days
1 100 10
1 200 10
As iam new to sql,i am little confuse to use SUM() based on above condition.
This query below produces two columns: EmployeeID, totalDays.
SELECT EmployeeID, SUM(totalDays) totalDays
FROM tableName
GROUP BY EmployeeID
follow-up question: why is in your desired result the projectId is 1 and 2?
Here are two approaches
Declare #t Table(ProjectId Int, EmployeeId Int,TotalDays Int)
Insert Into #t Values(1,100,1),(1,100,1),(1,100,2),(1,100,6),(1,200,8),(1,200,2)
Approach1:
Select ProjectId,EmployeeId,TotalDays = Sum(TotalDays)
From #t
Group By ProjectId,EmployeeId
Approach2:
;With Cte As(
Select
ProjectId
,EmployeeId
,TotalDays = Sum(TotalDays) Over(Partition By EmployeeId)
,Rn = Row_Number() Over(Partition By EmployeeId Order By EmployeeId)
From #t )
Select ProjectId,EmployeeId,TotalDays
From Cte Where Rn = 1
Result
ProjectId EmployeeId TotalDays
1 100 10
1 200 10
select min("Project ID")as 'Project ID',"Employee ID"
, SUM("Total Days") as 'Total Days'
from table1
group by "Employee ID"