New column with rowtotals - sql

I'm having some trouble to achieve the folowing result.
This is my current table:
ID NR COST
1 7001 100
2 7001 50
3 7020 800
4 7020 190
5 7050 205
6 7050 80
And this is the table I want to achieve:
ID NR COST TOTAL
1 7001 100 150
2 7001 50 150
3 7020 800 990
4 7020 190 990
5 7050 205 285
6 7050 80 285
So I want to create an extra column, where the sum of the same 'NR' column is.
I have tried working with SUM, but then the whole sum of the cost column is taken.
This is my current query:
SELECT distinct id, nr, cost, sum(cost) as total
FROM customers
group by id, nr, cost

You can use a subquery to calculate the total for each NR and then just add it to the original result:
SELECT id,
nr,
cost,
A.subtotal AS TOTAL
FROM table1
INNER JOIN (SELECT nr,
Sum(cost) AS subTotal
FROM table1
GROUP BY nr) AS A
ON table1.nr = A.nr

You can self join with an aggregate query:
SELECT id, mytalbe.nr, cost, total
FORM mytable
JOIN ON (SELECT nr, SUM(cost) AS total
FROM mytable
GROUP BY nr) t ON t.nr = mytable.nr

Related

Get the total Count and Sum of total Amount from down line record using SQL Server CTE

How can we Count and Sum all down-line rows to their up-line using SQL.
Current data:
ST_ID UPLINE AMOUNT
---------------------------
44930 52001 400
52016 52001 300
52001 9024 432
76985 9024 100
12123 35119 234
12642 35119 213
12332 23141 654
Here in above table, uplinedata 52001 two ST_ID with amount 400 and 300 each with total sum of 700 and ST_ID has 52001 as well with Amount 400, so total amount for 5201 will be 400 + 300 + 432 = 1132 and again upline 9024 has ST_ID of 52001 with 432 + 700 with total of 1132.
Expected Output:
UPLINE AMOUNT CNT
------------------------
52001 1132 2 (400 +300 + 432 | 1+1+1)
9024 1232 4 (700 + 432 + 100 | 2+1+1 = 4)
35119 447 2 (234 + 213 | 1+1 = 2)
23141 654 1
I thought of recursive CTE but could not able to gather the logic. Do anyone have any idea to achieve this. I am using SQL Server 2016.
As I understood, the Upline column is connected to ST_ID column, and you want to find the sum and count grouped by (Upline + all the matched values from ST_ID). i.e. Upline = 9024 is connected to ST_ID = 52001, so the sum for Upline = 9024 will be (432 + 100 from 9024 plus 300 + 400 from 52001).
You could use a recursive CTE as the following:
With CTE As
(
Select ST_ID, Upline, Amount From table_name
Union All
Select T.ST_ID, T.Upline, C.Amount
From table_name T Join CTE C
On C.Upline = T.ST_ID
)
Select Upline,
Sum(Amount) As Amount,
Count(*) As Cnt
From CTE
Group By Upline
See a demo.
Update according to the new requirement (in addition to the sum of the the previous query add the sum of values where ST_ID=Upline):
With CTE As
(
Select * From table_name
Union All
Select T.ST_ID, T.Upline, C.AMOUNT
From table_name T Join CTE C
On C.Upline = T.ST_ID
)
Select C.Upline,
Sum(C.Amount) + ISNULL(Sum(Distinct T.Amount), 0) As Amount,
Count(*) + Count(Distinct T.Amount) As Cnt
From CTE C Left Join table_name T
On C.Upline = T.ST_ID
Group By C.Upline
See demo.

SQL - Summing/counting rows based on matching columns

I have the 2 following tables
Tracking
tracking_id item_extension quantity
a 144 100
b 144 200
c 250 150
Account
tracking_id account
a 999
b 999
c 999
Here's my query -
SELECT sum(qty) as qty, count(item_extension) as total, t.tracking_id, item_extension, account
FROM Tracking t
INNER JOIN Account a ON t.tracking_id = a.tracking_id
GROUP BY t.tracking_id, item_extension, account
What I want to happen here is get count of item_extension and sum of quantity based on matching account/item_extension fields. So because there are 2 rows with matching account and item_extension fields, it should sum up 2 of them like so:
qty total tracking_id item_extension account
300 2 a 144 999
300 2 b 144 999
150 1 c 250 999
Instead I get this result:
qty total tracking_id item_extension account
100 1 a 144 999
200 1 b 144 999
150 1 c 250 999
Is there a good way of doing this?
You want to count item_extension values that are not in the current row. So, use window functions. I think this does what you want:
SELECT sum(qty) as qty,
sum(count(*)) over (partition by item_extension) as total,
t.tracking_id, item_extension, account
FROM Tracking t
INNER JOIN Account a ON t.tracking_id = a.tracking_id
GROUP BY t.tracking_id, item_extension, account;

SQL DB2 Toad - Sum from two tables by ID

I was hoping to find the sum from two tables with columns ID and Amount, grouping by ID.
My first attempt was to UNION the two tables first and then conduct a sum and group by, but I was hoping to know of a better way.
Inputs:
Table 1
ID Amount
123 100
123 100
145 500
167 600
Table 2
ID Amount
123 100
123 100
145 500
199 600
Output
ID Amount
123 400
145 1000
167 600
199 600
You can do:
select id, sum(amount) as amount
from (
select id, amount from table_1
union all
select id, amount from table_2
) x
group by id

Get the product with highest sales

I need a query to return the products that have been sold most often.
I have two tables to work with.
Product
IDPRO(PK) DESCRIP STOCK PRICE
4000 PIZZA 7 2000
4001 HAMBURGUESA 8 800
4002 PAELLA 1 1000
4003 CORDERO 5 3000
4004 COMIDA CHINA 9 500
4005 ALBONDIGAS 9 500
Details
IDPRO(FK) Amount
4002 2
4003 1
4004 1
4002 3
4002 1
4003 100
4004 50
4004 3
4005 10
The result would be something like this
CORDERO
Since it is the product with the highest amount of sold units.
If you need the total quantity you could use sum and group by on the joined tables
select t1.IDPRO, t1.DESCRIP, sum(t2.Amount) total
FROM Product t1
INNER JOIN DETAILS t2 on t2.IDART = t1.IDPRO
GROUP BY t1.IDPRO, t1.DESCRIP
ORDER BY total desc
First find the sum of CANTIDAD column for each product and select top 1 row and join to table 1.
Query
select top 1 t1.IDPRO, t1.DESCRIP, t2.total
from Product t1
join (
select IDART, sum(Amount) as total
from Details
group by IDART
)t2
on t1.IDPRO = t2.IDART
order by t2.total desc;
Try somethink like this for top 1:
WITH MAIN AS(
SELECT main.IDPRO, main.DESCRIP, main.CANTIDAD from Details det
LEFT JOIN Product main ON main.IDPRO=det.IDART)
SELECT TOP 1 * from MAIN

SQL Query to continuously bucket data

I have a table as follows:
Datetime | ID | Price | Quantity
2013-01-01 13:30:00 1 139 25
2013-01-01 13:30:15 2 140 25
2013-01-01 13:30:30 3 141 15
Supposing that I wish to end up with a table like this, which buckets the data into quantities of 50 as follows:
Bucket_ID | Max | Min | Avg |
1 140 139 139.5
2 141 141 141
Is there a simple query to do this? Data will constantly be added to the first table, it would be nice if it could somehow not recalculate the completed buckets of 50 and instead automatically start averaging the next incomplete bucket. Ideas appreciated! Thanks
You may try this solution. It should work even if "number" is bigger than 50 (but relying on fact that avg(number) < 50).
select
bucket_id,
max(price),
min(price),
avg(price)
from
(
select
price,
bucket_id,
(select sum(t2.number) from test t2 where t2.id <= t1.id ) as accumulated
from test t1
join
(select
rowid as bucket_id,
50 * rowid as bucket
from test) buckets on (buckets.bucket - 50) < accumulated
and buckets.bucket > (accumulated - number))
group by
bucket_id;
You can have a look at this fiddle http://sqlfiddle.com/#!7/4c63c/1 if it is what you want.