Removing duplicate values from a dataset - sql-server-2008

I am developing an SSRS report with the following dataset (Table-1). I am grouping by Account and Period. My goal is to get the Total Expense and the Budget within a group. Because the Budget data is duplicated per group, I cannot use SUM() function for Budget. How do I remove the duplicates so the new dataset looks like this? (Table-2) Please advice. Thank you for your time.
Table-1
ID Account Period Expense Budget
1 100 201301 20 100
2 100 201301 30 100
3 100 201302 10 150
4 100 201302 40 150
5 200 ...................
Table-2
ID Account Period Expense Budget
1 100 201301 20 100
2 100 201301 30 NULL
3 100 201302 10 150
4 100 201302 40 NULL
5 200 ...................

If you really want to make duplicate budgets null try this update command
please check sqlfiddle http://sqlfiddle.com/#!3/1e619/11
Update table1
set budget = null
where id in
(
select aa.id from
(
select id,row_number()
over(partition by Budget order by Period) as rno
from table1
) aa
where rno > 1
);
select * from table1;
good luck.

I would use a windowed function if you have to do that grouping in SQL. If you can do it in SSRS just add a 'Row Grouping Parent' it would be better.
For SQL I would do this:
declare #Temp table ( ID int identity, Account int, period int, expense int, budget int);
insert into #Temp values (100, 201301, 20, 100),(100, 201301, 30, 100),(100, 201302, 10, 150),(100, 201302, 40, 150)
select *
from #Temp
select
ID
, Account
, Period
, Expense
, case when (row_number() over(partition by Budget order by Period) = 1) then Budget end as Budget-- only shows first occurrence of an order amount ordering by person
from #Temp

Related

How to substrate number from the sum of columns of a table based on the id

I have a table named deposit, below
dep_id
deposit_amount
comp_id
1
100
1
2
100
1
3
100
1
When I run the query below I get the next updated table which is not what I want :
query = em.createNativeQuery("UPDATE deposit SET deposit_amount = (SELECT SUM(deposit_amount) - 50) WHERE comp_id = :comp_id");
query.setParameter("comp_id", comp_id);
The updated table after the above query
dep_id
deposit_amount
comp_id
1
50
1
2
50
1
3
50
1
But I want when I substract 50 or any amount it should get the sum of the columns and minus the amount from the sum not from each column. Below
dep_id
deposit_amount
comp_id
1
83.3
1
2
83.3
1
3
83.3
1
Because the sum is 300, and 300-50 = 250
Please how should I do this?
Using a common table expression, you can use this query. Get the total deposit amount per comp_id. Then join this new table (called total) to deposit on comp_id. Subtract 50 from the sum.
WITH total as(
select comp_id,
sum(deposit_amount) as total
from
deposit
group by
comp_id
)
select dep.dep_id,
ttl.total - 50 as deposit_amount,
dep.comp_id
from
deposit dep
inner join
total ttl
on
dep.comp_id = ttl.comp_id
Sample:
dep_id
deposit_amount
comp_id
1
250
1
2
250
1
3
250
1
You should compute deposit amount in a separate query, then join back your two tables on matching "comp_id" value
WITH cte AS (
SELECT DISTINCT comp_id,
SUM(deposit_amount) OVER(PARTITION BY comp_id) AS amount
FROM deposit
)
UPDATE deposit
INNER JOIN cte
ON deposit.comp_id = cte.comp_id
SET deposit_amount = cte.amount - 50
WHERE deposit.comp_id = :comp_id;
In your final query it should look like:
query = em.createNativeQuery("WITH cte AS (SELECT DISTINCT comp_id, SUM(deposit_amount) OVER(PARTITION BY comp_id) AS amount FROM deposit) UPDATE deposit INNER JOIN cte ON deposit.comp_id = cte.comp_id SET deposit_amount = cte.amount - 50 WHERE deposit.comp_id = :comp_id");
query.setParameter("comp_id", comp_id);
Check the demo here.

Getting wrong output for subtraction of columns in two tables in SQL statement

I have two tables, Deposit table and Withdraw. These two tables have a same column "game_name" which is foreign key to the Game table.
Game
game_name
Deposit
game_name
d_amount
d_bonus
Withdraw
game_name
w_amount
Sample data:
Deposit
[GameName] [d_amount] [d_bonus]
-------------------------------
Mario 100 10
Mario 200 20
Mario 300 30
Withdraw
[GameName] [w_amount]
----------------------
Mario 30
Mario 50
Desire output : (100+200+300+10+20+30) - (30+50) = 580
I need to write a sql statement to calculate the total credit of the game, (SUM of d.amount+d.bonus) - (SUM of w.amount) and that will be the total credit for the game Mario.
Here is my sql statement:
SELECT SUM(deposit.d_amount+deposit.d_bonus) - SUM(withdraw.w_amount) from deposit
cross join withdraw
where deposit.game_name and withdraw.game_name = "Mario";
I'm getting the wrong output.
Please help me on this.
You can use union all and aggregation:
select game_name,
sum(amount + bonus - w_amount)
from ((select d.game_name, d.amount, d.bonus, 0 as w_amount
from deposits d
) union all
(select w.game_name, w.amount, 0 as bonus, 0 w.w_amount
from withdraw w
)
) dw
group by d.game_name;
Note: This includes all game_name, even those that are in only one table.
Second, this assumes that the values in the columns are not NULL. If that is possible, then use COALESCE().

LIMIT and Group By? How do I return the lowest 100 earning customers by country? SQL

Hi I’ve a table database1
3 columns : customer_id , income , country
Customer_id
1001
1002
...
Income
5000
6000
7000
Country
SG
HK
VN
...
How do I write a query that returns the lowest 100 earning customers per country?
Is it possible to return:
Customer ID | country code
1003 SG
1004 SG
...
1007 VN
...
So on
Thanks!
On mySQL 8 you can leverage a window function for this:
SELECT * FROM
(
SELECT
country,
customer_id,
row_number() over(partition by country order by income asc) earn_rank
FROM table
)x
WHERE x.earn_rank <= 100
You can conceive that this window function will sort the rows by country then by income, then start counting up from 1. Each time the country changes the row numbering starts over from 1 again. This means that for every country there will be a row numbered 1 (with the lowest income), and a 2, 3 etc. If we then wrap it up in another outer query that selects only rows where the number is less than 101 we get 100 rows per country

How to update the value of the least value row with the value of the maximum value row using MySQL?

I have a table which has a combination of item_id and payment_id columns as a key.
Every two rows have the same item_id value.
This is how the table looks.
item_id payment_id amount
1 140 1000
1 141 3000
2 141 500
2 145 600
3 4 4000
3 735 9000
How to subtract the amount value of the least payment_id row from the amount value of the maximum payment_id row (of the two rows with the same item_id) using MySQL?
To clarify, this is how the table I want.
item_id payment_id amount
1 140 1000
1 141 2000 : 3000 - 1000
2 141 500
2 145 100 : 600 - 500
3 4 4000
3 735 5000 : 9000 - 4000
Cheer!
You can get the new amount with this query:
select p1.item_id, p1.payment_id, p1.amount - (
select p0.amount
from payments p0
where p0.item_id = p1.item_id
and p0.payment_id < p1.payment_id
order by p0.payment_id
limit 1
) as new_amount
from payments p1
having new_amount is not null;
It will subtract the amount of the "last" row with the same item_id (if present).
You can then use that query in the UPDATE statement as derived table joined to your original table:
update payments p
join (
select p1.item_id, p1.payment_id, p1.amount - (
select p0.amount
from payments p0
where p0.item_id = p1.item_id
and p0.payment_id < p1.payment_id
order by p0.payment_id
limit 1
) as new_amount
from payments p1
having new_amount is not null
) p1 using (item_id, payment_id)
set p.amount = p1.new_amount;
Demo: http://rextester.com/DJD86481
UPDATE tt JOIN (SELECT item_id, MAX(payment_id) mp , (SUBSTRING_INDEX(GROUP_CONCAT(amount ORDER BY payment_id DESC),',',1) - SUBSTRING_INDEX(GROUP_CONCAT(amount ORDER BY payment_id ),',',1)) maxdif FROM tt GROUP BY item_id) s
ON tt.item_id=s.item_id
SET tt.amount =s.maxdif
WHERE tt.payment_id =s.mp AND tt.item_id=s.item_id;
SELECT * FROM tt;
See it working

How to sum duplicated values in a Group(SSRS 2005)

How to sum duplicated values in a Group*(SSRS 2005).*
eg.
My query returns values like the following:
CusID Discount Amount
1 20 1000
1 20 2000
1 5 700
2 15 1500
2 15 3000
But,when I sum Discount amount in Group Footer, I cannot get the total values like below. I get 45 for CusID 1 instead of 25. Please help me to solve this problem.Thanks.
CusID Discount Amount
1 20 1000
1 20 2000
1 5 700
------------------------
Total 25 3700
2 15 1500
2 15 3000
------------------------
Total 15 4500
well without what your actual data looks like, i can only provide you a code example based off of the data you provided.
declare #table table (CustID int, Discount int, Amount int)
insert into #table (CustID,Discount,Amount)
select 1 as CusID,20 as Discount,1000 as Amount
union all
select 1,20,2000
union all
select 1,5,700
union all
select 2,15,1500
union all
select 2,15,3000
select
CustID,
sum(Discount) as Discount,
sum(Amount) as Amount
from
(
select
CustID,
Discount,
SUM(Amount) as Amount
from #table
group by CustID, Discount
) a
group by CustID
One slight simplification to DForcek42's answer by using the sum(distinct x)
declare #table table (CustID int, Discount int, Amount int)
insert into #table (CustID,Discount,Amount)
select 1 as CusID,20 as Discount,1000 as Amount
union all
select 1,20,2000
union all
select 1,5,700
union all
select 2,15,1500
union all
select 2,15,3000
select
CustID,
sum(distinct Discount),
SUM(Amount) as Amount
from #table
group by CustID