How to get first row value from each group and apply to first record only, rest will be 0 or null in SQL Server - sql-server-2008

This is our output:
category
Rev
trandate
BankAccNo
Fee
Credit Cards
1
01-09-2022
10000175090
576
Credit Cards
1
01-09-2022
10000175090
576
Loan
2.2
01-01-2022
10000175090
678
Loan
2.2
01-02-2022
10000175090
678
Loan
3.4
01-03-2022
10000175090
678
Loan
2.2
01-05-2022
10000175090
678
Loan
2.2
01-06-2022
10000175090
678
Loan
5.81
01-08-2022
10000175090
678
Loan
2.2
01-09-2022
10000175090
678
But we are looking for expected result should be look like mentioned below.
category
Rev
trandate
BankAccNo
Fee
Credit Cards
1
01-09-2022
10000175090
576
Credit Cards
1
01-09-2022
10000175090
0
Loan
2.2
01-01-2022
10000175090
678
Loan
2.2
01-02-2022
10000175090
0
Loan
3.4
01-03-2022
10000175090
0
Loan
2.2
01-05-2022
10000175090
0
Loan
2.2
01-06-2022
10000175090
0
Loan
5.81
01-08-2022
10000175090
0
Loan
2.2
01-09-2022
10000175090
0
Final result would look like 2nd table mentioned on the above.

Using ROW_NUMBER() along with a CASE expression:
SELECT category, Rev, trandate, BankAccNo,
CASE WHEN ROW_NUMBER() OVER (PARTITION BY category, BankAccNo ORDER BY trandate) = 1
THEN Fee ELSE 0 END AS Fee
FROM yourTable
ORDER BY 1, 5;
In the event that two or more records from the same category happen to fall on the same earliest transaction date, then only one of those records will arbitrarily report the actual fee value, with the other tie records reporting 0.

Related

Add and Substract one Row value to another row value in same table using mysql

Below is my table tbl_wallet. I want to add and subtract amount in same table addition and subtraction on the basis of credit and debit key
sno
w_userid
w_amount
w_type
1
263
100
credit
2
263
200
credit
3
263
100
credit
4
263
100
debit
Below is my query for getting detail
SELECT wl.w_userid
, wl.w_type
, wl.w_amount
, DATE_FORMAT(w_date,' %D %M %Y %r') AS w_date
, SUM(w_amount)
FROM tbl_wallet AS wl
WHERE wl.w_userid=263
ORDER BY wl.w_date DESC;
But i want the output like Below
sno
w_userid
w_amount
w_type
Balance
1
263
100
credit
100
2
263
200
credit
300
3
263
100
credit
400
4
263
100
debit
300
SELECT *,
SUM(CASE w_type WHEN 'credit' THEN w_amount
WHEN 'debit' THEN -w_amount
ELSE 0
END) OVER (PARTITION BY w_userid
ORDER BY sno ASC) AS Balance
FROM source_table

Get the first n lines for group after summing up

I am practising my skills in MySQL using the Sakila DB.
I would I have created a view called rentals_customer_store_film_category with is the union of customers, payments, rentals, film, and category tables.
I would now like to get the top 5 films by income. Meaning that I would lie to sum up all incomes of each film by store and then return the first 5.
I tried the below code but it does not work.
I cannot figure out what is wrong with it
Any help?
SELECT store_id, film_id, income
FROM
(SELECT film_id, store_id, sum(amount) as income,
#store_rank := IF(#current_store = store_id, #store_rank + 1, 1) AS store_rank,
#current_store := store_id
FROM rentals_customer_store_film_category
group by store_id, film_id
ORDER BY store_id, income DESC, film_id
) ranked
WHERE store_rank <= 5
RESULTS BELOW. As you can see, it does not stop at the fifth row per store. It shows all films by store while I would like only the top 5 for store:id 1 and top 5 for store id 2.
store_id film_id income
1 971 134.82
1 879 132.85
1 938 127.82
1 973 123.83
1 865 119.84
1 941 117.82
1 267 116.83
1 327 110.85
1 580 106.86
1 715 105.85
1 897 104.85
...
...
...
...
2 878 127.83
2 791 127.82
2 854 123.83
2 946 117.86
2 396 113.81
2 369 111.84
2 764 110.85
2 260 110.84
2 838 110.82
2 527 109.83
2 893 106.84
2 71 102.87
2 8 102.82
...
...
...
...
The order in this case is important to compare the previous store_id with the current,try this:
SELECT store_id, film_id, income
FROM
(SELECT film_id, store_id, sum(amount) as income,
#First compare previus with current
#store_rank := IF(#prev_store = store_id, #store_rank + 1, 1) AS store_rank,
#asign previus store
#prev_store := store_id
FROM films
group by store_id, film_id
ORDER BY store_id, income DESC, film_id
) ranked
WHERE store_rank <= 5

SELECT without grouping

How get results without grouping it?
My table
id user_id amount currency_id type status
5 2 2.00 1 0 0
6 3 3.00 1 0 0
4 1 1.00 1 0 0
7 4 4.00 1 0 0
8 5 3.00 1 1 0
I do the following select
SELECT id, user_id, amount, currency_id, SUM( amount )
FROM market
WHERE amount <=3
AND type = 0
AND status = 0
Result:
id user_id amount currency_id SUM( amount )
5 2 2.00 1 6.00
How get this result:
id user_id amount currency_id SUM( amount )
5 2 2.00 1 0 6.00
6 3 3.00 1 0 6.00
4 1 1.00 1 0 6.00
If your intent is to return individual records that meet this criteria AND sum them up and you don't actually need the SUM value as a field on every row (not sure why you would), then I would suggest looking at the GROUP BY ... WITH ROLLUP modifier. It works like this:
SELECT id, user_id, SUM(amount) AS `amounts`, currency_id
FROM market
WHERE amount <=3
AND type = 0
AND status = 0
GROUP BY id WITH ROLLUP
Here I am grouping by id because this will keep the individual records intact as this value is unique
You output would look like this:
id user_id amounts currency_id
5 2 2.00 1
6 3 3.00 1
4 1 1.00 1
NULL 3 6.00 1
Note the last record provides the rollup to the SUM() function. Also note that values for user_id and currency_id in the rollup row are indeterminate as they were not part of the GROUP BY or aggregation. As such, they have no meaning.
You can do join
SELECT id,
user_id,
amount,
currency_id,
a.totalAmount
FROM market
CROSS JOIN
(
SELECT SUM(amount) totalAmount
FROM market
WHERE amount <=3
AND type = 0
AND status = 0
) a
WHERE amount <=3
AND type = 0
AND status = 0
or using inline subquery,
SELECT id,
user_id,
amount,
currency_id,
(
SELECT SUM(amount) totalAmount
FROM market
WHERE amount <=3
AND type = 0
AND status = 0
) totalAmount
FROM market
WHERE amount <=3
AND type = 0
AND status = 0
Here you go:
SELECT id, user_id, amount, currency_id, t2.total
FROM market, (
SELECT SUM(amount) AS total
FROM market
WHERE amount <=3
AND type = 0
AND status = 0
) AS t2
WHERE amount <=3
AND type = 0
AND status = 0

SSRS summary of nested groups at outer group footer

I have a report ouput like this,
it has nested groups, outer group is on Business Partners and the inner one is on Currency Code.
Busines Partner1
Opening Balance for USD as of 2013-10-01
Transaction 1..
Transaction n..
USD Totals
Balance for EUR as of 2013-10-01
Transaction 1..
Transaction n..
EUR Totals
Busines Partner2
Opening Balance for USD as of 2013-10-01
Transaction 1..
Transaction n..
USD Totals
Balance for EUR as of 2013-10-01
Transaction 1..
Transaction n..
EUR Totals
What I need is on Business Partner Group Footer, I'd like to display overall outstanding balances for each currency code. Something like;
Busines Partner1
Opening Balance for USD as of 2013-10-01
Transaction 1..
Transaction n..
USD Totals
Balance for EUR as of 2013-10-01
Transaction 1..
Transaction n..
EUR Totals
(Assume below section is Business Partner1 Group Footer)
Currency, Opening Balance, Sum of In Period, Overall
USD 200.00 300.00 500
EUR 150.00 400.00 550
Total 1050
Busines Partner2
Opening Balance for USD as of 2013-10-01
Transaction 1..
Transaction n..
USD Totals
Balance for EUR as of 2013-10-01
Transaction 1..
Transaction n..
EUR Totals
(Assume below section is Business Partner2 Group Footer)
Currency, Opening Balance, Sum of In Period, Overall
USD 100.00 300.00 400
EUR 250.00 300.00 550
Total 950
Question is how can I achieve this?
I am pulling data from an SP, with opening balances for a given date.
Number of currencies are not known beforehand.
And the report has 2 groups, outer group is on Biz.PartnerId inner one is on currency
code.
SSRS 2008 R2 ( I can upgrade to latest and greatest if this is
an issue to consider.)
I think that you just have to structure your groups right..
based on the following sample data:
SELECT 'BusinessPartner1' BusinessPartner, 'EUR' CurrencyType, 100 Amount, 122 TotalSpend UNION
SELECT 'BusinessPartner1' BusinessPartner, 'GBP' CurrencyType, 111 Amount, 301 TotalSpend UNION
SELECT 'BusinessPartner2' BusinessPartner, 'EUR' CurrencyType, 81 Amount, 191 TotalSpend UNION
SELECT 'BusinessPartner2' BusinessPartner, 'GBP' CurrencyType, 13 Amount, 93 TotalSpend UNION
SELECT 'BusinessPartner2' BusinessPartner, 'USD' CurrencyType, 30 Amount, 32 TotalSpend UNION
SELECT 'BusinessPartner3' BusinessPartner, 'GBP' CurrencyType, 78 Amount, 42 TotalSpend UNION
SELECT 'BusinessPartner3' BusinessPartner, 'USD' CurrencyType, 210 Amount, 61 TotalSpend UNION
SELECT 'BusinessPartner3' BusinessPartner, 'EUR' CurrencyType, 12 Amount, 71 TotalSpend
If you structure your groups like this, (1 parent, 1 child, 1 adjacent to child):
Then you get the below output, which I think is the same sort of thing that you're after. To get exactly what you need I think that you would also need a details child group on each of the adjacent groups

aggregation: sum columns by ID and average columns by id (gender and location unchanged)

I want to aggregate my data. I want to sum all of of the columns, for a given ID, and average the other column. Here is what I have and what I would like. Also, I need to put this into a new table.
ID Cash charge total proportion gender location
1 3.00 2.00 5.00 .66 m 28972
1 2.00 1.00 3.00 .66 m 28972
1 3.00 0.00 3.00 1 m 28972
1 4.00 2.00 6.00 .66 m 28972
2 3.00 3.00 6.00 .5 f 37352
2 4.00 6.00 10.00 .4 f 37352
This is what I want in a new table. I want to sum the cash, charge, and total for a given ID and I want to average the proportion for a given ID. Gender and location need to be there, but not summed or averaged
ID SumCash Sumcharge Sumtotal AvgProportion Gender Location
1 12.00 5.00 17.00 .745 m 28972
2 7.00 9.00 16.00 .45 f 37352
You can get the result by using the aggregate functions sum() and avg():
select id,
sum(cash) SumCash,
sum(charge) sumCharge,
sum(total) sumTotal,
avg(proportion) avgProportion
from yt
group by id;
See SQL Fiddle with Demo
Edit, with the new columns that you added you can still get the result by using the aggregate functions. You will just need to include the gender and location columns in the GROUP BY clause:
select id,
sum(cash) SumCash,
sum(charge) sumCharge,
sum(total) sumTotal,
avg(proportion) avgProportion,
gender,
location
from yt
group by id, gender, location;
See SQL Fiddle with Demo
Here the query what you need:
SELECT ID, SUM(A.CASH), SUM(A.CHARGE), SUM(A.TOTAL), SUM(A.AVGPROPORTION)/COUNT(ID)
FROM A
WHERE A.ID = ID
GROUP BY A.ID