I want to add the values in the column cost ,amt- if there is a flag 1 and 2 for same person id on same date. please help. Thank you. Column are:
id date cost amt flag
455 05/25/2013 150 110 1
455 05/25/2013 20 45 2
456 08/17/2013 140 60 1
456 08/17/2013 15 20 2
457 09/28/2013 135 10 1
457 09/28/2013 8 40 2
458 11/09/2013 10 30 1
output should be:
id date cost amt flag
455 05/25/2013 170 155 1
456 08/17/2013 155 80 1
457 09/28/2013 143 50 1
458 11/09/2013 10 30 1
Just for diversity, check out my solution. It uses over (partition by ) for calculation and distinct for filtering out the duplicates.
select distinct o.ID, o.Date,
SUM(o.COST) OVER(PARTITION BY o.ID, o.Date) as cost
,SUM(o.AMT) OVER(PARTITION BY o.ID, o.Date) as amt
,MIN(FLAG) OVER(PARTITION BY o.ID, o.Date) as flag
from orders o
order by o.ID, o.Date
SqlFiddle proof
It's inspired by this article.
Not really sure what you want to do with flag, but you need GROUP BY like:
SELECT id, date, SUM(cost), Sum(amt), 1 as flag
FROM yourTable
GROUP BY id,date
SELECT ID, DATE , SUM(COST), SUM(AMT), MIN(Flag)
FROM TABLE
GROUP BY ID, DATE
If you need flag 1 AND 2 in the same date for the same id then this should work:
SELECT id, date, SUM(cost), SUM(amt) , flag
FROM yourtable a
WHERE flag=1
AND EXISTS (SELECT 1 FROM yourtable b WHERE a.id=b.id AND b.flag=2 AND a.date=b.date)
GROUP BY id, date, flag
Related
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
)
I have a data set that looks like:
cust city hotel_id amount
-------------------------------
A 1 252 3160
B 1 256 1893
C 2 105 2188
D 2 105 3054
E 3 370 6107
F 2 110 3160
G 2 150 1893
H 3 310 2188
I 1 252 3160
J 1 250 4000
K 3 370 5000
L 3 311 1095
Query to display the top 3 hotels by revenue (Sum of amount) for each city?
Since same hotel can be booked by other customer in same city so we need to sum the amount to find total amount.
Expected output:
city hotel_id amount
---------------------------
1 252 6320
1 250 4000
1 256 1893
2 105 5242
2 110 3160
2 150 1893
3 370 11107
3 310 2188
3 311 1095
SELECT
t.city, t.hotel_id, t.amount
FROM
(
SELECT city, hotel_id, SUM(amount) AS amount,
ROW_NUMBER() OVER (PARTITION BY city ORDER BY SUM(amount) DESC) AS rn
FROM yourTable
GROUP BY city, hotel_id
) t
WHERE t.rn <= 3
ORDER BY t.city, t.amount DESC;
Demo here:
Rextester
To get the total sum for each hotel_id you need to group by that column first, then group by the city for syntax purposes. The #tmp table here should have all of the data you need, so then you just have to select the top 3 entries for each city from there.
SELECT city, hotel_id, SUM(amount) AS 'total' INTO #tmp
FROM [table]
GROUP BY hotel_id, city
(SELECT TOP 3 *
FROM #tmp
WHERE city = 1)
UNION
(SELECT TOP 3 *
FROM #tmp
WHERE city = 2)
UNION
(SELECT TOP 3 *
FROM #tmp
WHERE city = 3)
I am using SQL Server 2008 R2 and have a structure as below:
create table #temp( deptid int, regionid int)
insert into #temp
select 15000, 50
union
select 15100, 51
union
select 15200, 50
union
select 15300, 52
union
select 15400, 50
union
select 15500, 51
union
select 15600, 52
select deptid, regionid, RANK() OVER(PARTITION BY regionid ORDER BY deptid) AS 'RANK',
ROW_NUMBER() OVER(PARTITION BY regionid ORDER BY deptid) AS 'ROW_NUMBER',
DENSE_RANK() OVER(PARTITION BY regionid ORDER BY deptid) AS 'DENSE_RANK'
from #temp
drop table #temp
And output currently is as below:
deptid regionid RANK ROW_NUMBER DENSE_RANK
--------------------------------------------------
15000 50 1 1 1
15200 50 2 2 2
15400 50 3 3 3
15100 51 1 1 1
15500 51 2 2 2
15300 52 1 1 1
15600 52 2 2 2
My requirement however is to row_number over regionid column but by grouping and not row by row. To explain better, below is my desired result set.
deptid regionid RN
-----------------------
15000 50 1
15200 50 1
15400 50 1
15100 51 2
15500 51 2
15300 52 3
15600 52 3
Please let me know if my question is unclear. Thanks.
Use dense_rank() over (order by regionid) to get the expected result.
select deptid, regionid,
DENSE_RANK() OVER( ORDER BY regionid) AS 'DENSE_RANK'
from #temp
Partitioning within a rank/row_number window function will assign numbers within the partitions, so you don't need to use a partition on regionid to order the regionids themselves.
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
I have a table like this
id ref status date
1 150 P 10/01/2010
2 150 P 11/01/2010
3 150 P 12/01/2010
4 151 P 10/01/2010
5 151 C NULL
6 152 P 11/01/2010
7 152 P 12/01/2010
8 152 C NULL
And what i want is to retrieve all the records that either have a status equals to C and (for those who have the status P) the last record according to the column date.
For example:
id ref status date
3 150 P 12/01/2010
5 151 C NULL
8 152 C NULL
So far I have tried to do subquerys but i dont get to have the last record according to date.
I´m using Sybase 8.0.2.4542. Thank you so much guys!!
Try to use the solution:
select id, ref, status, max(date)
from table
where status = 'P'
group by id, ref, status, date
union all
select id, ref, status, date
from table
where status = 'C'
with one query:
select *from
(select id, ref, status, max(date)
from table
where status = 'P'
group by id, ref, status, date
union all
select id, ref, status, date
from table
where status = 'C') RES