Left outer join with condition sql - sql

would anybody know if there is way to do conditional left outer join? I have ledger tables with actuals and reference department table from which I want to assign BMDIV.
But department reference table contains LC number or = 'xx'
What I want to do is to join ledger table with department table on LCTRYNUM, LC and DEPTNUM but in the case of LC = '**' join would be only LCTRYNUM and DEPTNUM.
Ledger acutal table
LCTRYNUM
LC
DEPTNUM
Amount
618
40
30813
100
618
50
30813
200
618
60
30813
300
618
10
30813
100
Business Division reference table
LCTRYNUM
LC
DEPTNUM
BMDIV
618
**
30813
30
618
10
30813
2P
Expected result would be this
LCTRYNUM
LC
DEPTNUM
Amount
BMDIV
618
40
30813
100
30
618
50
30813
200
30
618
60
30813
300
30
618
10
30813
100
2P

You can use two left joins, the first to bring in direct matches and the second for the default match:
select a.*, coalesce(d.bmdiv, d_default.bmdiv) as bmdiv
from actual a left join
divisions d
on a.lc = d.lc left join
divisions d_default
on d_default.lc = '**'

Related

Is there is way to get SUM() of column without GROUPING by joining multiple tables in SQL Server

I am getting SUM() of amount in CrowdfundedUser table by GROUP BY CrowdfundID but difficult to get SUM() because all columns are unique.
Crowdfund:
CrowdfundID
GoalAmount
StartedDate
9
10000
09/02/2022
5
20000
10/02/2022
55
350000
11/02/2022
444
541256
12/02/2022
54
78458
13/02/2022
CrowdfundedUser:
ID
User ID
CrowdfundID
Amount
744
12214
9
1000
745
4124
5
8422
746
12214
55
784
747
12214
444
874
748
64554
54
652
CrowdfundiPaymentTransaction:
CrowdfundedUserID
Invoice
Amount
PaymentDate
744
RA45A14124
1000
09/02/2022
745
RA45A12412
8422
10/02/2022
746
RA45U14789
784
11/02/2022
747
RA45F12457
874
12/02/2022
748
RA45M00124
652
13/02/2022
My query :
SELECT
c.CrowdfundID,
SUM(cu.Amount),
SUM(cpt..Amount)
FROM
Crowdfund c
INNER JOIN
CrowdfundedUser cu ON c.CrowdfundID = cu.CrowdfundID
INNER JOIN
CrowdfundiPaymentTransaction cpt ON cu.ID = cpt.CrowdfundedUserID
GROUP BY
c.CrowdfundID
SELECT c.CrowdfundID,
SUM(cu.Amount) OVER (
ORDER BY c.CrowdfundID) Amount,
SUM(cpt..Amount) OVER (
ORDER BY c.CrowdfundID) CptAmount
FROM Crowdfund c
INNER JOIN CrowdfundedUser cu ON c.CrowdfundID = cu.CrowdfundID
INNER JOIN CrowdfundiPaymentTransaction cpt ON cu.ID = cpt.CrowdfundedUserID

select unique combination in two overlap datasets

For example, in SAS, I have 5 IDs in dataset A(below left). There is a dataset B,(could potentially contain some A's IDs,below right).What I need is to find one unique combination( A is the primary outcome dataset) on A and B has same sex, age range within 5 and income range within 10000.Tt is possible that there are a lot of b.id could merge with a.id. But here's the kick, I can only use b.id once. In this case, 101 merge with 106, 102 merge with 111,103 merge with 112,105 merge with 110. Sorry I have a hard time how to describe my question. Hopefully it is clear enough. Thanks!
ID sex age income ID sex age income
101 F 30 20000 106 F 26 21000
102 M 20 10000 102 M 20 10000
103 F 38 30000 110 M 45 44000
104 M 55 35000 111 M 19 14000
105 M 43 45000 112 F 33 34000
outcome
ID_a sex_a age_a income_a ID_b sex_b age_b income_b
101 F 30 20000 106 F 26 21000
102 M 20 10000 111 M 19 14000
103 F 38 30000 112 F 33 34000
104 M 55 35000
105 M 43 45000 110 M 45 44000
select a.Id, b.Id from SetA a
left join SetB b on a.sex = b.sex and
a.age between b.age - 5 and b.age + 5 and
a.income between b.income - 10000 and b.income + 10000
You should be able to use the techniques used in the answers to this question to do your fuzzy matching while making sure that each b.id is only used once.
The idea is to load your B dataset into a temporary array / hash object, so you can keep track of which b.ids have already been used while matching it onto A.
SELECT
A.ID,
B.ID
FROM lefttable A
INNER JOIN righttable B
ON (A.sex = B.sex) AND (A.age BETWEEN B.age -5 AND B.age + 5) AND (A.income BETWEEN B.income -10000 AND B.age + 10000)

SQL join two table together

I have the following tables:
table1
a b
1 100
2 200
3 300
4 400
table2
c b
55 100
55 200
56 300
I want to get the following output:
55 100 1
55 200 2
55 300 -
55 400 -
56 100 -
56 200 -
56 300 3
56 400 -
I tried the following:
SELECT *
FROM table1
full JOIN table2
output:
a b c a
1 100 55 100
1 100 55 200
1 100 55 100
1 100 55 200
2 300 56 300
....
also I tried:
SELECT *
FROM table1
join table2 on table1.b = table2.b
union
SELECT *
FROM table2
join table1 on table1.b = table2.b
the output:
1 100 55 100
1 200 55 200
3 300 56 300
Is this possible in microsoft SQL 2012? and how
I'm not completely sure I understand your expected outcome, but it sounds like you're looking for a FULL OUTER JOIN.
SELECT table1.a, COALESCE(table1.b, table2.b), table2.c
FROM table1
FULL OUTER JOIN table2 ON table1.b = table2.b
This will get the fields from table1 and, if any exist, map them to those from table2.
Given your example, it will return the following table.
A B C
1 100 55
2 200 55
3 300 56
4 400 (null)
I know that isn't the same as the expected result you gave, but this will correlate the data that actually exists.
I'm requesting clarification in a comment and will revise this as necessary.

FULL JOIN doesn't work in two ways

I'm trying to write a FULL JOIN statement in SQL but it doesn't work as fine as I would like.
Here is my full statement
SELECT
t.tacNom, bh.heuresChiffrees,
SUM(ISNULL(heures,0)) + SUM(ISNULL(minutes,0)/60) as HeuresRealisee, (ISNULL(bh.heuresChiffrees,0) - (SUM(ISNULL(heures,0)) + (SUM(ISNULL(minutes,0))/60))) as Solde,
(SUM(DISTINCT minutes)%60) as Soldeminutes
FROM tbl_BalanceHeures bh
FULL OUTER JOIN tbl_HeuresTimbrage_new ht ON ht.idProjet = bh.proIdProjetExterne
AND ht.idxTache = bh.idxTache
AND ht.idxDep= bh.idxDepartement
INNER JOIN tbl_Taches t on t.idTache = bh.idxTache
WHERE proIdProjetExterne = '00Z 000104' AND bh.idxDepartement = 184
GROUP BY t.tacNom ,bh.heuresChiffrees
Here are the result of the statement
idTache heuresChiffrees HeuresRealisee Solde
332 25 0 25
330 50 0 50
327 100 42 58
331 100 23 77
Here are the records in my table tbl_Balance and the statement
select t.idTache, bh.heuresChiffrees
from tbl_BalanceHeures bh
INNER JOIN tbl_Taches t on t.idTache = bh.idxTache
WHERE proIdProjetExterne= '00Z 000104' AND bh.idxDepartement = 184
idTache heuresChiffrees
330 50
331 100
327 100
332 25
Here are the records in tbl_HeuresTimbrage and the statement
Select t.idTache, ht.heures as heuresRealisees
From tbl_HeuresTimbrage_new ht
INNER JOIN tbl_Taches t on t.idTache = ht.idxTache
WHERE idProjet= '00Z 000104' AND ht.idxDep = 184
idTache heuresRealisees
327 32
331 23
327 10
334 4
So, In my FULL JOIN Statement I am expected to find
IdTache heuresChiffrees Heures Realisees
327 100 10
330 50 NULL (or 0)
331 100 23
332 25 NULL (or 0)
334 NULL(or 0) 4
I've tried to put my WHERE clause in the Full JOIN but it doesn't work
It's most likely because of your WHERE clause. It is acting on the joined result, and so if the A side is null, it will eliminate those rows.
You can change it to be a condition of the join instead, as so:
FROM A
FULL OUTER JOIN B
ON B.idProjet = A.proIdProjetExterne
AND B.idxTache = A.idxTache
AND B.idxDep= A.idxDepartement
AND A.proIdProjetExterne = 'xxx'
AND A.idxDepartement = 184
However, without seeing your actual data or schema, this is a bit of a guess...

Sqlite substract sums (with group by) with JOIN and duplicates

I previously found the solution to my problem but unfortunately I lost files on my harddrive and I can't find the statement I managed to produce.
I have 2 tables T2REQ and T2STOCK, both have 2 columns (typeID and quantity) and my problem reside in the fact that I can have multiple occurences of SAME typeID in BOTH tables.
What I'm trying to do is SUM(QUANTITY) grouped by typeID and substract the values of T2STOCK from T2REQ but since I have multiple occurences of same typeID in both tables, the SUM I get is multiplied by the number of occurences of typeID.
Here's a sample of T2REQ (take typeID 11399 for example):
typeID quantity
---------- ----------
34 102900
35 10500
36 3220
37 840
11399 700
563 140
9848 140
11486 28
11688 700
11399 390
4393 130
9840 390
9842 390
11399 390
11483 19.5
11541 780
And this is a sample of T2STOCK table :
typeID quantity
---------- ----------
9842 1921
9848 2400
11399 1700
11475 165
11476 27
11478 28
11481 34
11483 122
11476 2
And this is where I'm at for now, I know that the SUM(t2stock.quantity) is affected (multiplied) because of the JOIN 1 = 1 but whatever I tried, I'm not doing it in the right order:
SELECT
t2req.typeID, sum(t2req.quantity), sum(t2stock.quantity),
sum(t2req.quantity) - sum(t2stock.quantity) as diff
FROM t2req JOIN t2stock ON t2req.typeID = t2stock.typeID
GROUP BY t2req.typeID
ORDER BY diff DESC;
typeID sum(t2req.quantity) sum(t2stock.quantity) diff
---------- ------------------- --------------------- ----------
563 140 30 110
11541 780 780 0
11486 28 40 -12
11483 19.5 122 -102.5
9840 390 1000 -610
40 260 940 -680
9842 390 1921 -1531
9848 140 2400 -2260
11399 1480 5100 -3620
39 650 7650 -7000
37 1230 116336 -115106
36 28570 967098 -938528
35 33770 2477820 -2444050
34 102900 2798355 -2695455
You can see that SUM(t2req) for typeID 11399 is correct : 1480
And you can see that the SUM(t2stock) for typeID 11399 is not correct : 5100 instead of 1700 (which is 5100 divided by 3, the number of occurences in t2req)
What would be the best way to avoid multiplications because of multiple typeIDs (in both tables) with the JOIN for my sum substract ?
Sorry for the wall of text, just trying to explain as best as I can since english is not my mother tongue.
Thanks a lot for your help.
You can aggregate before join:
SELECT
t2req.typeID,
t2req.quantity,
t2stock.quantity,
t2req.quantity - t2stock.quantity as diff
FROM
(SELECT TypeID, SUM(Quantity) Quantity FROM t2req GROUP BY TypeID) t2req JOIN
(SELECT TypeID, SUM(Quantity) Quantity FROM t2stock GROUP BY TypeID) t2stock
ON t2req.typeID = t2stock.typeID
ORDER BY diff DESC;
Fiddle sample: http://sqlfiddle.com/#!7/06711/5
You can't do this in a single aggregation:
SELECT
COALESCE(r.typeID, s.typeID) AS typeID,
COALESCE(r.quantity, 0) AS req_quantity,
COALESCE(s.quantity, 0) AS stock_quantity,
COALESCE(r.quantity, 0) - COALESCE(s.quantity, 0) AS diff
FROM (
SELECT rr.typeID, SUM(rr.quantity) AS quantity
FROM t2req rr
GROUP BY rr.typeID
) r
CROSS JOIN (
SELECT ss.typeID, SUM(ss.quantity) AS quantity
FROM t2stock ss
GROUP BY ss.typeID
) s ON r.typeID = s.typeID
ORDER BY 4 DESC;