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.
Related
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
I have the following table structure..
emp_id | base_rate | base_sal | effective_on
1001 26.22 1200 2015-10-12
1001 26.00 1100 2015-11-12
1001 26.00 1100 2015-12-12
1002 18 1200 2015-10-12
1002 19 1100 2015-11-12
I need to find get the last updated base_rate with effective_on date for each emp_id
Like output ..
1001 26.00 1100 2015-11-12
1002 19 1100 2015-11-12
See, for 1001 2015-11-12 is selected instead of 2015-12-12 which is latest as the base_rate is same and hence previously effective from 2015-11-12
I have tried.. everything.. not able to find the exact query..
This method is simple and easy to understand.
1) Assign rank for all the effective dates in descending order by partitioning
for each employee.
2) Select all the required fields for the last updated effective date from the
inner query and display the result.
SELECT emp_id,base_rate,base_sal
FROM
(
SELECT *,
ROW_NUMBER() OVER ( PARTITION BY emp_id ORDER BY effective_on DESC ) AS rn
FROM table
)
WHERE rn = 1;
One method is to generate a subset of employees with max effective on and join back to the base set..
In the below we generate set "B" with Emp_ID and ME (max effective) and then we join back to the entire data set in the table and use the columns emp_ID and ME to limit the data in the base set and return all columns we care about.
Put in English:
We generated a data set for all the employess with only their max effective date, and then joined this data set back to the base set to limit the data in the base set to only contain records for employees with their most recent effective_on date.
SELECT A.Emp_ID, A.Base_Rate, A.Base_Sal, min(C.Effective_On)
FROM Table A
INNER JOIN (SELECT emp_ID, Max(Effective_on) ME
FROM Table A
GROUP BY Emp_ID) B
on A.Emp_ID = B.Emp_ID
and A.Effective_ON = B.ME
INNER JOIN TABLE C
on C.Emp_ID = A.Emp_ID
and C.Base_Rate= A.Base_rate
and C.base_Sal = A.Base_Sal
GROUP BY A.Emp_ID, A.Base_Rate, A.Base_Sal
This is more or less database agnostic whereas a row_number and limit would not work on mySQL as it doesn't support window functions.
You can first get the minimum date each base_rate becomes effective on for every employee and then take the max from there. Here is how you can do it using row_number() in oracle:
with temp(emp_id, base_rate, base_sal, effective_on)
as (select 1001, 26.22, 1200, '2015-10-12' from dual union all
select 1001, 26.00, 1100, '2015-11-12' from dual union all
select 1001, 26.00, 1100, '2015-12-12' from dual union all
select 1002, 18, 1200, '2015-10-12' from dual union all
select 1002, 19, 1100, '2015-11-12' from dual
)
SELECT emp_id,base_rate,base_sal,effective_on FROM(
SELECT temp2.*,
row_number() OVER (PARTITION BY EMP_ID ORDER BY effective_on DESC) AS rn2
FROM
(
SELECT temp.*,
row_number() OVER (PARTITION BY EMP_ID, BASE_RATE ORDER BY effective_on) AS rn
FROM temp
) temp2
WHERE rn = 1
)
WHERE rn2 = 1;
I need some help to solve an issue with my query. I want to join the output of two select statements:
1st
select extract(year from createdDate) as year,
count(extract(year from createdDate)) as count
from table
where to_user_id= 322
group by extract(year from createdDate);
and its output
Year Count
2014 18
2015 117
2016 9
and 2nd query
select count(extract(year from createdDate)) as count
from table
where userId=322
group by extract(year from createdDate);
and its output
Count
18
110
11
I want to add this two tables into one table.
I want that type of output,
Year Count Count
2014 18 18
2015 117 110
2016 9 11
Note that I use to_user_id in query 1 but userId in query 2.
I tried to solved out this thing but I got repeated values in the output.
Anyone know the solution?
Write them as subqueries and join them together.
SELECT a.year, a.count AS t_user_count, b.count AS user_count
FROM (select YEAR(create_date) AS year, COUNT(*) AS count
FROM table
WHERE to_user_id = 322
GROUP BY year) AS a
JOIN (SELECT YEAR(create_date) AS year, COUNT(*) AS count
FROM table
WHERE user_id = 322
GROUP BY year) AS b
ON a.year = b.year
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)
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