Calculating sum of children's balance for each parent - sql

I have two tables having parent-child relationship
Table1
| Account_no | Main_account_no | bla bla
+------------+-----------------+----------
| 234 | 111 |
| 235 | 111 |
| 222 | 112 |
| 220 | 112 |
The second:
Table2
| Account_no | Balance | bla bla
+------------+-----------------+----------
| 234 | 10 |
| 235 | 15 |
| 222 | 55 |
| 220 | 45 |
What I need is to calculate the sum of balance of child accounts for each parent account.
The expected result is
| Main_account_no | Balance |
+-----------------+---------+
| 111 | 35 |
| 112 | 100 |
I am trying to use
SELECT MAIN_ACCOUNT_NO, SUM((SELECT BALANCE FROM TABLE2 WHERE ACCOUNT_NO = A.ACCOUNT_NO)) OVER (PARTITION BY MAIN_ACCOUNT_NO)
FROM TABLE1 A
GROUP BY MAIN_ACCOUNT_NO
But I get the ORA-00979: not a GROUP BY expression
Where did I do wrong?

Since this apparently isn't homework... :-)
First let's get the main_account_nos alongside the balances:
select
Table1.Main_account_no,
Table1.Account_no,
Table2.Balance
from
Table1
join Table2 on Table1.Account_no = Table2.Account_no
Gives
| Main_account_no | Account_no | Balance |
+-----------------+------------+-----------------+
| 111 | 234 | 10 |
| 111 | 235 | 15 |
| 112 | 222 | 55 |
| 112 | 220 | 45 |
Now we can easily group as required:
select
Table1.Main_account_no,
sum(Table2.Balance) as total
from
Table1
join Table2 on Table1.Account_no = Table2.Account_no
group by
Table1.Main_account_no

Related

Exclude subsets from a table which has superset values too

Table1 has employee ids and codes where each employee has both super-set code and subset codes.
+-------------+------+
| Employee ID | Code |
+-------------+------+
| 111 | 18 |
| 111 | 19 |
| 111 | 20 |
| 111 | 21 |
| 222 | 40 |
| 222 | 41 |
| 222 | 42 |
+-------------+------+
Table2 has super-set code and subset code.
+---------------+-------------+
| Superset code | Subset code |
+---------------+-------------+
| 18 | 19 |
| 18 | 20 |
| 18 | 21 |
| 40 | 41 |
| 40 | 42 |
+---------------+-------------+
I want output with employee id and super-set code alone.
Expected result table:
+-------------+------+
| Employee ID | Code |
+-------------+------+
| 111 | 18 |
| 222 | 40 |
+-------------+------+
How can I derive this output using sql query?
I think you want exists:
select t1.*
from table1 t1
where exists (select 1 from table2 t2 where t2.supersetcode = t1.code);
For performance, you want an index on table2(supersetcode).

Count Distinct and extract Values not in Group By

I am trying to get a full table with an additional column with a count distinct grouped by only a set of fields, not the full table.
Basically, I have this table:
| mandt | ktopl | yhkonto | yhhykto | yhbwkz |
|-------|-------|------------|---------|--------|
| 111 | SAG | 0034600000 | 346 | 1 |
| 111 | SAG | 0034600000 | 346 | 21 |
| 111 | SAG | 0034600000 | 346 | 82 |
| 111 | SAG | 0034600000 | 346 | 87 |
| 111 | SAG | 0039410000 | 39410 | 1 |
| 111 | SAG | 0039410000 | 39410 | 21 |
| 111 | SAG | 0039410000 | 39410 | 82 |
| 111 | SAG | 0039410000 | 39410 | 87 |
| 111 | SAG | 0039630000 | 39630 | 1 |
| 111 | SAG | 0039630000 | 39630 | 21 |
and I want to get this result, with an additional column, where I get the count of distinct values of yhhykto grouping by mandt, ktopl and yhkonto:
| mandt | ktopl | yhkonto | yhhykto | yhbwkz | cnt_yhhykto |
|-------|-------|------------|---------|--------|-------------|
| 111 | SAG | 0034600000 | 346 | 1 | 1 |
| 111 | SAG | 0034600000 | 346 | 21 | 1 |
| 111 | SAG | 0034600000 | 346 | 82 | 1 |
| 111 | SAG | 0034600000 | 346 | 87 | 1 |
| 111 | SAG | 0039410000 | 39410 | 1 | 1 |
| 111 | SAG | 0039410000 | 39410 | 21 | 1 |
| 111 | SAG | 0039410000 | 39410 | 82 | 1 |
| 111 | SAG | 0039410000 | 39410 | 87 | 1 |
| 111 | SAG | 0039630000 | 39630 | 1 | 1 |
| 111 | SAG | 0039630000 | 39630 | 21 | 1 |
I have a working query:
select distinct yh010.mandt,
yh010.ktopl,
yh010.yhkonto,
yh010.yhhykto,
yh010.yhbwkz,
yh010_x.cnt_yhhykto
from yh010
inner join (
select distinct yh010.mandt,
yh010.ktopl,
yh010.yhkonto,
count(distinct yh010.yhhykto) as cnt_yhhykto
from yh010
group by yh010.mandt, yh010.ktopl, yh010.yhkonto
) yh010_x
on yh010_x.mandt = yh010.mandt
and yh010_x.ktopl = yh010.ktopl
and yh010_x.yhkonto = yh010.yhkonto
;
But this inner join with itself doesn't seem the best solution. Or is it?
I was thinking more like in terms of:
select yh010.mandt,
yh010.ktopl,
yh010.yhkonto,
yh010.yhhykto,
yh010.yhbwkz
count( distinct yh010.yhhykto
) over ( group by yh010.mandt, yh010.ktopl, yh010.yhkonto
) as cnt_dist
from yh010
;
But Incorrect syntax near the keyword 'distinct'.
Should I keep that working query or is there any better option?
The fiddle can be found here
Thank you!
Based on this description:
I want to get this result, getting the count of distinct values of
yhhykto grouping by mandt, ktopl and yhkonto
You want this query:
select y.mandt, y.ktopl, y.yhkonto,
count(distinct y.yhhykto)
from yh010 y
group by y.mandt, y.ktopl, y.yhkonto;
Your actual results and resulting query don't match the description, leaving me a bit confused.
Antonio,
Could you please test following SELECT statement with CTE expression
with cte as (
select
distinct mandt, ktopl, yhkonto, yhhykto
from TBL1
)
select
TBL1.*, (
select count(cte.yhhykto)
from cte
where
TBL1.mandt = cte.mandt and
TBL1.ktopl = cte.ktopl and
TBL1.yhkonto = cte.yhkonto
) as cnt
from TBL1

select with multiple conditiions in where in

With tables table1 and table2need select the rows of table1 for those locationIds and hours where tier in table2 is high
table1
+------------+------+---------+----------+
| locationId | hour | metric1 | metric2 |
+------------+------+---------+----------+
| 1111 | 10 | 200 | 40 |
| 1111 | 9 | 300 | -20 |
| 1111 | 11 | 1800 | 300 |
| 1122 | 9 | 600 | 800 |
| 1122 | 11 | 2300 | -10 |
| 1133 | 8 | 10000 | 30 |
+------------+------+---------+----------+
table2
+------------+------+-------+---------+
| locationId | hour | value | tier |
+------------+------+-------+---------+
| 1111 | 10 | 1300 | high |
| 1111 | 9 | 900 | medium |
| 1111 | 11 | 200 | low |
| 1122 | 9 | 100 | low |
| 1122 | 11 | 2300 | high |
| 1133 | 8 | 1400 | high |
+------------+------+-------+---------+
If it was one column - say locationId I could have done something like
select * from table1
where locationId in (select locationId from table2 where tier='high');
How do I do this when the locationId, hour pair need to be compared?
output
+------------+------+---------+----------+
| locationId | hour | metric1 | metric2 |
+------------+------+---------+----------+
| 1111 | 10 | 200 | 40 |
| 1122 | 11 | 2300 | -10 |
| 1133 | 8 | 10000 | 30 |
+------------+------+---------+----------+
I think a simple join should handle this:
SELECT t1.*
FROM table1 t1
INNER JOIN table2 t2
ON t1.locationId = t2.locationId AND
t1.hour = t2.hour
WHERE t2.tier = 'high'
Output:
Demo here:
Rextester
The INNER JOIN keyword selects all rows from both tables as long as there is a match between the columns in both tables.
select * from table1 t1
inner join table2 t2 on t1.locationId =t2.locationId
where t2.tier='high'
Use EXISTS method to get your result :
SELECT *
FROM table1 TBL1 WHERE EXISTS
(
SELECT 1 FROM table2 TBL2 WHERE TBL1.locationId = TBL2.locationId AND
TBL1.hour = TBL2.hour AND TBL2.tier = 'high'
)

Is it Possible to Join these 2 Tables

I have 2 tables
Table A:
+------------+----------+
| Entry From | Entry To |
+------------+----------+
| 100 | 103 |
| 104 | 105 |
| 106 | 109 |
+------------+----------+
Table B:
+-------+-------+
| Entry | Value |
+-------+-------+
| 100 | 10 |
| 101 | 3 |
| 102 | 7 |
| 103 | 2 |
| 104 | 9 |
| 105 | 17 |
| 106 | 3 |
| 107 | 3 |
| 108 | 6 |
| 109 | 5 |
+-------+-------+
Desired result:
+------------+----------+-------------+
| Entry From | Entry To | Total Value |
+------------+----------+-------------+
| 100 | 103 | 22 |
| 104 | 105 | 26 |
| 106 | 109 | 17 |
+------------+----------+-------------+
Any solutions/advice is welcome.
Thanks to any help in advance!
Please try:
Select
a.EntryFrom, a.EntryTo, sum(Value) TotalValue
From TableA a INNER JOIN TableB b ON b.Entry between a.EntryFrom and a.EntryTo
Group by a.EntryFrom, a.EntryTo
What you're looking for is a subquery maybe.
SELECT
A.Entry_From, A.Entry_To,
(SELECT SUM(B.Value) FROM B
WHERE B.Entry BETWEEN A.Entry_From AND A.Entry_To) AS Total_Value
FROM A
It also depends on what version of SQL so YMMV :)
Here is a working fiddle: http://www.sqlfiddle.com/#!2/afbac/2 using this query:
select a.idxFrom, a.idxTo, sum(b.value) as total
from a inner join b on b.idx >= a.idxFrom and b.idx <= a.idxTo
group by a.idxFrom, a.idxTo

Access SQL : How to retrieve all records from 2 tables (no matter they do not have record in the other table)

I'm creating inventory report mainly to show current qty, sum of qty that was reserved from customers and Total Qty that available .
As I used LEFT JOIN and RIGHT JOIN but it couldn't work, so I'm thinking of UNION function but I could't make it work. Could you please help me. Thank you very much.
tbl_inventory
inv_id | pd_id | inv_qty_act | inv_date | inv_note
1 | 001 | 120 | 20-Sep-12|
2 | 003 | 387 | 1-Oct-12 |
tbl_reserve
res_id | cust_id | res_date | res_duedate | pd_id | res_qty | if_sent | res_note
3 | 10 | 01-Oct-12| 17-Oct-12 | 001 | 135 | |
4 | 9 | 01-Oct-12| 24-Oct-12 | 001 | 253 | |
5 | 22 | 01-Oct-12| 17-Oct-12 | 001 | 132 | |
6 | 2 | 01-Oct-12| 24-Oct-12 | 002 | 446 | |
tbl_product
pd_id | pd_name
001 | des1
002 | des2
003 | des3
tbl_pdtn_startup
pdtn_st_id | pd_id | pdtn_qty_est
2 | 002 | 200
3 | 003 | 100
Output that I want :
pd_id| pd_name| inv_qty_act|pdtn_qty_est| Sum(res_qty)| Total[(inv_qty_est) - Sum(res_qty)]
001 | des1 | 120 | 0 | 520 | -400 -->(120-520)
002 | des2 | 0 | 200 | 446 | -446 -->(0-446)
003 | des3 | 387 | 100 | 0 | 387
what about this?
SELECT
tbl_product.pd_id,
tbl_product.pd_name,
( SELECT Sum(inv_qty_act) FROM tbl_inventory AS t1
WHERE t1.pd_id=tbl_product.pd_id) AS SumOfinv_qty_act,
( SELECT Sum(pdtn_qty_est) FROM tbl_pdtn_startup AS t2
WHERE t2.pd_id =tbl_product.pd_id) AS SumOfpdtn_qty_est,
( SELECT Sum(res_qty) FROM tbl_reserve AS t3
WHERE t3.pd_id=tbl_product.pd_id) AS SumOfres_qty,
IIF(ISNULL([SumOfinv_qty_act]),0,[SumOfinv_qty_act])-
IIF(ISNULL([SumOfres_qty]),0,[SumOfres_qty]) AS Total
FROM
tbl_product;