select price having max year in another column - sql-server-2008

I have following select result
Code Price Year
1 200 2013
1 100 2012
2 250 2011
2 275 2012
2 300 2010
But I want following something like this with one extra column which hold price based on maximum year,
Code Price Year ExPrice
1 200 2013 200
1 100 2012 200
2 250 2011 275
2 275 2012 275
2 300 2010 275
Sorry for bad English and wrong way for asking this question.

You can do it with cross apply and select top 1 ... order by:
select Code, Price, Year, ExPrice
from TableName T
cross apply (
select top 1 Price
from TableName
where Code = T.Code
order by Year desc
) p(ExPrice)
or row_number and join (whatever you prefer):
;with cte as (
select Code, Price as ExPrice, rn = row_number() over (partition by Code order by Year desc)
from TableName
)
select T.Code, Price, Year, ExPrice
from TableName T
join cte on cte.Code = T.Code and cte.rn = 1
SQLFiddle sample

Try something like this:
SELECT T1.Code, T1.Price, T1.Year, T2.Price
FROM Table T1
INNER JOIN Table T2 ON T1.Code = T2.Code AND
T2.Year = (SELECT MAX(Year) FROM Table WHERE Table.Code = T2.Code)

Related

SQL finding max value of column where another column has got maximum but repetable value

I have following table:
id year month
1 2019 9
2 2019 10
3 2019 11
4 2019 12
5 2020 1
6 2020 2
7 2020 3
8 2020 4
I need to select max value of column month but only from where year has got max value.
In that case i need to select row
id max_year max_month
8 2020 4
I tried to make it with this
SELECT m.id, m.max_year, MAX(m.month) AS max_month FROM (SELECT id, month, MAX(year) AS max_year FROM tbl_months GROUP BY id) AS m GROUP BY m.id
Unnfortunately I get
id max_year max_month
5 2020 1
6 2020 2
7 2020 3
8 2020 4
Any clues why?
Is there another way to make it simpler and cleaner?
Thanks.
Use order by and limit;
select t.*
from t
order by year desc, month desc
limit 1;
with cte as
(
select * from temp where year = ( select max(year) from temp)
),cte2 as
(
select * from temp where month = ( select max(month) from temp)
)
select * from cte2
As another option
select t1.*
from t t1
where m = (select max(t2.m) from t t2 where y = (select max(t3.y) from t t3))
This way called subquery. I am not sure if this is faster vs order by/limit option, but might be depend on index.

Access Join without Double Counting

I have two tables. One with amounts in quarterly increments, the other with amounts in annual increments. I want to join the two and sum FEES and COUNTS without double counting.
Table 1
CLM_NUM Year Quarter FEES
1234 2016 1 100
1234 2016 2 100
1234 2016 3 100
1234 2016 4 100
Table 2
CLM_NUM Year COUNT
1234 2016 10
Desired Result:
CLM_NUM Year FEES COUNT
1234 2016 400 10
However, my query causes the counts to be counted four times resulting in 40, not 10.
How do I resolve this?
SELECT Table1.CLM_NUM, Table1.YEAR, Sum(Table1.FEES) AS SumOfFEES,
Sum(Table2.COUNT) AS SumOfCOUNT
FROM Table1 INNER JOIN Table2 ON (Table1.CLM_NUM = Table2.CLM_NUM) AND (Table1.YEAR = Table2.YEAR)
GROUP BY Table1.CLM_NUM, Table1.YEAR;
You can use a sub-query. The SUM in the sub-query means it would work even if table 2 wasn't yearly (i.e. there were more rows per CLM_NUM/Year key).
SELECT
t1.clm_num,
t1.year,
sum(t1.fees),
(SELECT
sum(t2.count)
FROM
Table2 t2
WHERE t1.CLM_NUM = t2.CLM_NUM
AND t1.Year = t2.Year
GROUP BY
t2.CLM_NUM, t2.Year
) AS SumOfCount
FROM
Table1 t1
GROUP BY
t1.CLM_NUM, t1.Year
if access doesnt have max, use first
http://sqlfiddle.com/#!18/7ec1d/1
select t1.clm_num, t1.year,sum(t1.fees),max(t2.count)
from Table1 t1 inner join
Table2 t2 on t2.clm_num = t1.clm_num and (t1.YEAR = t2.YEAR)
GROUP BY t1.CLM_NUM, t1.YEAR

Get the Sum of Two Table GROUP BY date in year

I'm making a donation report, I have two tables tbldonation and tblpubdonation
I want to get their sum group by year.
tbldonation:
amount | received
100 : 2016-01-02 08:42:20
100 : 2015-12-01 09:20:00
tblpubdonation:
amount | received
100 : 2015-12-22 09:20:00
My query is :
SELECT * from
(
(SELECT YEAR(received) as YY, sum(amount) as AMT FROM tbldonation)
UNION ALL
(SELECT YEAR(received) as YY, sum(amount) as AMT FROM tblpubdonation)
) results
WHERE results.YY <= Curdate()
GROUP BY results.YY
ORDER BY results.YY DESC
I'm getting a result but it's not accurate.
It should be
YY | AMT
2016 : 100
2015 : 200
But my result is:
YY | AMT
2016 : 200
2015 : 100
The value is misplaced.
Try following for MySql (Since MySQL lacks support for FULL JOIN. we have to simulate It)
SELECT Yr , SUM(amountSum)
FROM ( SELECT SUM(ISNULL(t1.amount, 0)) AS amountSum ,
t1.year AS Yr
FROM tbldonation t1
GROUP BY t1.YEAR
UNION ALL
SELECT SUM(ISNULL(t2.amount, 0)) AS amountSum ,
t2.year AS Yr
FROM tblpubdonation t2
GROUP BY t2.YEAR
) Tbl
GROUP BY Tbl.Yr
Following works for T-SQL
SELECT SUM (ISNULL(t1.amount,0)) + SUM(ISNULL(t2.amount,0)), ISNULL(t1.YEAR,t2.YEAR)
FROM dbo.tbldonation t1
FULL OUTER JOIN dbo.tblpubdonation t2 ON t1.YEAR = t2.YEAR
GROUP BY t1.YEAR, t2.YEAR
You are using sum(amount) in the query .So in tbldonation the sum becomes .In pbldonationsum(amount)=100.At the end the order is given by years .So 2016 is at first and 2015 at the end.Year 2015 wont get the amount value 200 because union operator is used and both are having 2015 as common .So this is to chabged in the data itself as per me or else some data glitch.If I am wrong please suggest me also so that I can improve myself.
Thank you.
Regards, Raju.

how to get latest record or record with max corresponding date of all distinct values in a column in mysql?

For Example, I have table like this:
Date | Id | Total
-----------------------
2014-01-08 1 15
2014-01-09 3 24
2014-02-04 3 24
2014-03-15 1 15
2015-01-03 1 20
2015-02-24 2 10
2015-03-02 2 16
2015-03-03 5 28
2015-03-09 5 28
I want the output to be:
Date | Id | Total
---------------------
2015-01-03 1 20
2014-02-04 3 24
2015-03-02 2 16
2015-03-09 5 28
Here the distinct values are Id. I need latest Total for each Id.
You can use left join as
select
t1.* from table_name t1
left join table_name t2
on t1.Id = t2.Id and t1.Date >t2.Date
where t2.Id is null
http://dev.mysql.com/doc/refman/5.0/en/example-maximum-column-group-row.html
You can also use Max() in sql:
SELECT date, id, total
FROM table as a WHERE date = (SELECT MAX(date)
FROM table as b
WHERE a.id = b.id
)
You can do it as below
SELECT *
FROM YourTable D
WHERE date = (SELECT MAX(date) FROM YourTable WHERE ID = D.ID)
Another way is by using INNER JOIN
Find the latest date per ID then join result back to the table to get the value
select A.ID,A.Date,A.value
from yourtable A
INNER JOIN
(
select MAX(date) as Date,ID
from yourtable
group by ID
) B
ON A.ID =B.ID and A.Date = B.Date
The other answers didn't work for me. I found the following code, which worked great for me:
SELECT * FROM TABLE WHERE DATE IN (SELECT MAX(DATE) FROM TABLE)
I am using SSMS 2014, SQLServer

MySQL: Get difference between two values in one table (multiple userids)?

I was trying to find a solution but did not succeed even if it seems simple. So this might be a newbie question...
I have a table userscores with 3 columns:
date userid points
2012-05-01 1 23
2012-06-01 1 34
2012-07-01 1 44
2012-05-01 2 78
2012-06-01 2 94
2012-07-01 2 99
2012-06-01 3 2
2012-07-01 3 9
Now I need to get the difference of the points between 2012-05-01 and 2012-06-01 for each user.
Users' points that are not existing (example userid 3) have to be calculated as 2 - 0... for this I guess I can use COALESCE(qa_points,0).
I read about combining two subqueries for the calculation but failed implementing it.
Any help appreciated.
PS: This is not working:
SELECT t1.userid, t1.points - t2.points AS mpoints FROM (
SELECT userid,points FROM `userscores`
WHERE YEAR(date) = YEAR('2012-05-01')
AND MONTH(date) = MONTH('2012-05-01') )
AS t1
JOIN (
SELECT userid,points FROM `userscores`
WHERE YEAR(date) = YEAR('2012-04-01')
AND MONTH(date) = MONTH('2012-04-01') )
AS t2
ORDER BY mpoints DESC, t1.userid DESC;
I suppose your query will look like this:
SELECT ul.userid,
ul.points - COALESCE(uf.points, 0) AS points_difference
FROM userscores ul
LEFT JOIN
(SELECT userid, points FROM userscores WHERE `date` = '2012-05-01') AS uf
ON uf.userid = ul.userid
WHERE ul.date = '2012-06-01'
LEFT JOIN is used because you told that there may be no records for this user/former date combination.
Use this query:
SELECT t1.userid,
( t1.points - (case t2.date when '2012-05-01' then t2.points else 0 end))
AS mpoints FROM userscores as t1
INNER JOIN userscores as t2
ON t1.date = '2012-06-01' AND t1.userid=t2.userid