Fee Table
FeeId(PK)managerId amount Type
1 50 100 1
1 50 10000 39
1 50 50000 2
1 50 50000 3
1 50 50000 4
Manager Table
FeeId(FK)Split managerId
1 70 68
Desired Results:
FeeId managerId amount Type
1 50 30 1
1 68 70 1
1 50 3000 39
1 68 7000 39
1 50 15000 2
1 68 35000 2
1 50 15000 3
1 68 35000 3
1 50 15000 4
1 68 35000 4
This dataset is just one record, there are many more FeeId's in my data. A cross join would not take this into account. I basically want to cross join each manager based on the feeId.
The amount column is then recalculated to 70,30 for managerid 68,50 respectivly.
How do I do a cross join on each subset: WHERE f.feeId = m.feeId to get the desired results?
Example of cross join with incorrect results since the manager table will have more then 1 fee:
SELECT
f.feeId,
(cast(m.split as decimal) / 100) * f.amount as amount
FROM
dbo.fee f
CROSS JOIN dbo.manager m
As I understand this problem, you are trying to allocate the amount in fee between the two managers. The following query does this by cross joining an additional table, which is used to choose the data for each row.
select f.feeid,
(case when n.n = 1 then f.managerid
when n.n = 2 then m.managerid
end) as managerid,
(case when n.n = 1 then f.amount * (100 - m.split)/100
when n.n = 2 then f.amount * m.split/100
end) as amount, f.type
from fee f cross join
manager m cross join
(select 1 as n union all select 2) as n;
As a comment, this seems like a very unusual data structure.
It seems like this should work:
SELECT f.feeId, ,f.managerID, (cast(m.split as decimal) / 100) * f.amount as amount, f.type
FROM fee f
JOIN manager m
ON f.FeeID = m.FeeID
AND f.managerID = m.managerID
Related
I'm trying to reduce storage with packages included in sold products.
Products can have different amounts of same packages and invoice can have different amounts of products in separate lines. Action should be performed against certain invoiceID.
Simplified tables (summary is not column, just added to ease up calculation):
Inv_rows
InvID ProdID Qty *Summary*
999 100 2 *100 = 10*
999 101 2 *101 = 2*
999 102 2 *102 = 2*
999 103 2 *103 = 10*
999 100 8
999 103 8
Pack_to_prod
ProdID PackID Qty
100 A 2 *A = 20*
100 B 1 *B = 10*
101 A 1 *A = 2*
101 B 1 *B = 2*
102 A 3 *A = 6*
103 B 2 *B = 20*
Storage
ItemID Qty
A 100 *A = 28*
B 100 *B = 32*
**Desired Result**
Storage
ItemID Qty
A 72 *(100-28)*
B 68 *(100-32)*
What I have tried is:
UPDATE Storage
SET Storage.Qty = Storage.Qty -
(SELECT SUM (Inv_rows.Qty * Pack_to_prod.Qty) FROM Inv_rows
WHERE Inv_rows.ProdID IN (SELECT ProdID FROM Pack_to_prod
WHERE Pack_to_prod.PackID=Storage.ItemID) AND Inv_rows.InvId = 999
)
FROM Inv_rows, Storage, Pack_to_prod
WHERE Inv_rows.ProdID = Pack_to_prod.ProdID
AND Pack_to_prod.PackID = Storage.ItemID
AND Inv_rows.InvID = 999
But the problem is the 'IN' since it doesn't match the rows but I can't use '=' as 'where' results more than one line.
Then I tried to simplify it for myself (as I'm not a professional) with a select clause to understand what exactly needs to be done..
SELECT
Pack_to_prod.PackID AS PackageID,
Inv_rows.ProdID AS ProductID,
Inv_rows.Qty AS ProductQty,
Pack_to_prod.Qty AS PackageQtyPerProduct,
Inv_rows.Qty*Pack_to_prod.Qty AS PackageTotal,
Storage.Qty AS StorageQty,
Storage.Qty - (Inv_rows.Qty * Pack_to_prod.Qty) AS NewStorageQty
FROM Pack_to_prod,Inv_rows,Storage
WHERE Inv_rows.ProdID = Pack_to_prod.ProdID
AND Pack_to_prod.PackID = Storage.ItemID
AND Inv_rows.InvID = 999
GROUP BY Inv_rows.ProdID, Pack_to_prod.PackID, Pack_to_prod.Qty, Storage.Qty, Inv_rows.Qty
Which results as simple list showing the problem why they can't be just summed up:
PackageID ProductID ProductQty PackageQtyPerProduct PackageTotal StorageQty NewStorageQty
A 100 2 2 4 100 96
A 100 8 2 16 100 84
B 100 2 1 2 100 98
B 100 8 1 8 100 92
A 101 2 1 2 100 98
B 101 2 1 2 100 98
A 102 2 3 6 100 94
B 103 2 2 4 100 96
B 103 8 2 16 100 84
But can't figure out how to make it run 'line by line' so that each 'Pack_to_prod.Qty' would be handled separately.
Any help in right direction appreciated.
This seems like some aggregations and joins. To get the changes in values, then:
select pp.packid, sum(p.qty * pp.qty) as new_qty
from (select ir.prodid, sum(qty) as qty
from inv_rows ir
group by ir.prodid
) p join
Pack_to_prod pp
on pp.prodid = p.prodid
group by pp.packid;
You can then use this in an update:
update s
set s.qty = s.qty - pp.new_qty
from storage s join
(select pp.packid, sum(p.qty * pp.qty) as new_qty
from (select ir.prodid, sum(qty) as qty
from inv_rows ir
group by ir.prodid
) p join
Pack_to_prod pp
on pp.prodid = p.prodid
group by pp.packid
) pp
on pp.packid = s.itemid;
This was explained very well. The SQL code is user older coding conventions (such as JOIN conditions in the WHERE clause, instead of FROM) and isn't organized into subqueries properly. All the pieces are present though. I think something like this is what you're looking for.
with
inv_cte(ProdID, sum_qty) as (
select ProdID, sum(Qty)
from Inv_rows
group by ProdID),
pack_cte(PackID, prod_qty) as (
select pp.PackID, sum(pp.Qty*ic.sum_qty)
from Pack_to_prod pp
join inv_cte ic on pp.ProdID=ic.ProdID
group by pp.PackID)
select s.ItemID, s.Qty-p.prod_qty as ResultQty
from Storage s
join pack_cte p on s.ItemID=p.PackID;
Update statement
with
inv_cte(ProdID, sum_qty) as (
select ProdID, sum(Qty)
from Inv_rows
group by ProdID),
pack_cte(PackID, prod_qty) as (
select pp.PackID, sum(pp.Qty*ic.sum_qty)
from Pack_to_prod pp
join inv_cte ic on pp.ProdID=ic.ProdID
group by pp.PackID)
update s
set Qty=Qty-p.prod_qty
from Storage s
join pack_cte p on s.ItemID=p.PackID;
I've got a problem trying to join two tables, sample tables I have are as follows
Orders Table (Odr)
Order_No Item No Order_Type Req_Qty
100 A 2 45
101 B 1 32
102 F 2 23
103 A 4 23
104 C 3 14
105 B 5 43
Item Location Table (Loc)
Item_No Location Qty
A X 100
A Y 200
B X 150
B Y 50
C X 75
C Y 150
F X 250
F Y 60
What i want to see is, Location X's qty for each item of order types 1, 2 and 3 and for orders where Req_Qty is larger than 0
like below,
Order_No Item No Order_Type Req_Qty X_Qty
100 A 2 45 100
101 B 1 32 150
102 F 2 23 250
104 C 3 14 75
now ive written a query like below for this but i feel like its not giving me right results
select Odr.*, Loc.Qty
from Odr
inner JOIN Loc
ON Odr.ITEM_no = Loc.ITEM_no
where (SOPTYPE = '1' and Req_Qty >0
or SOPTYPE = '2' and Req_Qty >0
or SOPTYPE = '3' and Req_Qty >0) AND Loc.Location = 'X'
could someone pleas check this for me if this is the correct way to get the result i want
thanks
the query looks fine. but you could make it more readable:
select Odr.*, Loc.Qty
from Odr
inner JOIN Loc
ON Odr.ITEM_no = Loc.ITEM_no
where (SOPTYPE = '1' or SOPTYPE = '2' or SOPTYPE = '3')
and Req_Qty > 0
and Loc.Location = 'X'
or
select Odr.*, Loc.Qty
from Odr
inner JOIN Loc
ON Odr.ITEM_no = Loc.ITEM_no
where SOPTYPE IS IN('1', '2', '3')
and Req_Qty > 0
and Loc.Location = 'X'
I have following data
Components
componentid title
1 houseRent
2 medical
3 Travelling Allowance
empPayrollMaster
MasterID EmployeeID SalaryMonthID
1 101 1
2 102 1
3 103 1
empPayrollDetail
DetailID MasterID ComponentID amount
1 1 1 100
2 1 2 500
3 2 1 300
4 2 3 250
5 3 1 150
6 3 2 350
7 3 3 450
Required Output
EmployeeID MasterID ComponentID amount
101 1 1 100
101 1 2 500
101 1 3 0
102 2 1 300
102 1 2 0
102 2 3 250
103 3 1 150
103 3 2 350
103 3 3 450
To get the required output if i do left outer join between components and empPayrollDetail I get null in EmployeeID and MasterID and amount Columns. How to modify left join to get the required output
You need to do a CROSS JOIN on Components and empPayrollMaster to generate first all combination of employees and components. Then, do a LEFT JOIN on empPayrollDetail to achieve the result, using ISNULL(amount, 0) for NULL amounts.
SQL Fiddle
SELECT
epm.EmployeeID,
epm.MasterID,
c.ComponentID,
amount = ISNULL(epd.amount, 0)
FROM empPayrollMaster epm
CROSS JOIN Components c
LEFT JOIN empPayrollDetail epd
ON epd.MasterID = epm.MasterID
AND epd.ComponentID = c.ComponentID
Try this
select empPayrollMaster.EmployeeID,empPayrollMaster.MasterID,
Components.componentid,isnull(empPayrollDetail.amount,0)
from empPayrollMaster
left join Components
on empPayrollMaster.EmployeeID is not null
left join empPayrollDetail
on empPayrollDetail.MasterID = empPayrollMaster.MasterID
and empPayrollDetail.ComponentID = Components.componentid
Try this way
select c.EmployeeID,d.MasterID,c.ComponentID,isnull(d.amount,0) as amount from (
select * from Components a
Cross join empPayrollMaster b) c
left outer join empPayrollDetail d on d.componentid =c.componentid
As you want the component amount for each employee in the master table you should use a insull(payrole_detail.amount,0) or, as #Turophile pointed out, the SQL standard function coalesce(payrole_detail.amount,0) for the amounts column.
SELECT Customers.CustomerName, Orders.OrderID
FROM Customers
INNER JOIN Orders
ON Customers.CustomerID=Orders.CustomerID
ORDER BY Customers.CustomerName;
Dear All I have below two table
Table1
RecdId RecdNo
1 A/1
2 A/2
3 A/3
Table2
RecdId RecdAmt1 RecdAmt2 RecdAmt3
1 100 10 5
1 150 20 10
1 200 30 15
2 500 5 50
2 400 10 60
3 100 5
I want solution that how to join above two table with sum of Table1.RecdId = Tabble2.RecdId
Below result I require
RecdId RecdNo TotRecdAmt1 TotRecdAmt2 TotRecdAmt3
1 A/1 450 60 30
2 A/2 900 15 110
3 A/3 100 5
Thanking You,
You can inner join two tables and use a group by clause to calculate sum for each combination of RecdId and RecdNo:
select t1.RecdId
, t1.RecdNo
, sum(t2.RecdAmt1) as TotRecdAmt1
, sum(t2.RecdAmt2) as TotRecdAmt2
, sum(t2.RecdAmt3) as TotRecdAmt3
from tbl1 t1
join tbl2 t2 on t1.RecdId = t2.RecdId
group by t1.RecdId
, t1.RecdNo
SQLFiddle
SELECT T1.RECDID, T1.RECDNO, TotRecdAmt1, TotRecdAmt2, TotRecdAmt3
FROM TABLE1 T1, (SELECT RECdID, SUM(RecdAmt1) TotRecdAmt1, SUM(RecdAmt2) TotRecdAmt2,
SUM(RecdAmt3) TotRecdAmt3 FROM TABLE2 GROUP BY RECdID) T2
WHERE T1.RECdID = T2.RECDID;
SELECT Table1.RecdId,RecdNo,SUM(RecdAmt1) AS TotRecdAmt1,
SUM(RecdAmt2) AS TotRecdAmt2,
SUM(RecdAmt3) AS TotRecdAmt3
FROM Table1,Table2
WHERE Table1.RecdId=Table2.RecdId
GROUP BY Table1.RecdId,RecdNo
My query
with with_user_earns as (
-- get father information (start)
select father.id, father.str_name, father.id_father, father.ind_father_side_type, 1 as int_user_level from tb_user father where id = #v_user_id
union all
-- get son information (stop condition)
select son.id, son.str_name, son.id_father, son.ind_father_side_type, WUE.int_user_level + 1
from tb_user as son inner join with_user_earns as WUE on son.id_father = WUE.id
where son.id_father is not null and WUE.int_user_level < #v_max_level
)
select aux.*
from (
-- show result
select with_user_earns.id id_son, with_user_earns.str_name str_son_name, with_user_earns.id_father, father.str_name str_father_name, with_user_earns.ind_father_side_type, with_user_earns.int_user_level, isnull(sum(o.int_score), 0) as int_score
from with_user_earns inner join tb_order o on o.id_user = with_user_earns.id
inner join tb_user as father on father.id = with_user_earns.id_father
where o.dt_insert between #v_cycle_begin and #v_cycle_end and o.ind_payment_status = 3
group by with_user_earns.id, with_user_earns.str_name, with_user_earns.id_father, with_user_earns.ind_father_side_type, with_user_earns.int_user_level, father.str_name
) as aux
order by aux.int_user_level, aux.id_son
The table with_user_earns contains a lot of users (mult nivel hierarchy).
Then I want to join with tb_order to get int_score 0 if the user sell nothing and if the user sell anything I want the sum of it.
I tried put left join, full outer join, ... But no one works perfect
What a need to do?
My result:
id_son int_score
1 100
2 11100
3 100
10 300
Expected result:
id_son int_score
1 100
2 11100
3 100
4 0
5 0
6 0
7 0
8 0
9 0
10 300