SQL Joining tables but getting skipped values - sql

Hi i have joined to tables the code is below. Notice I have used A.Manad = B.Manad which joins data where the month of table A and B is equal. But sometimes table B dont have any data for that month. My code just skip the data, i would rather it just leave it empty or with a value of 0.
The Code takes a list of Orgnr which is swedish for company numbers and joins two tables where the orgnr is the same and the month is the same, but for some reason it doesnt join the data when the value is empty for one company. I still want the orgnr to show up in the joint table.
select Tillnr = A.tillnr, Orgnr = A.orgnr, Månad = A.Manad, Intrastat =
A.varde,Moms = B.vardeutf
into #Tabell1
From
IntrastatFsum A
left outer join
Momsuppg B
on A.Orgnr = B.Orgnr
where A.Orgnr in(
165563137933,165020456017,.......)
AND A.Ar = 2017
AND B.Ar = A.AR
AND A.Manad = 9
AND A.Manad = B.Manad
AND A.InfUtf = 'U'

You should move your WHERE clause AND A.Manad = B.Manad and AND B.Ar = A.AR to the LEFT JOIN clause.
In this way you will preserve all data from table IntrastatFsum:
select Tillnr = A.tillnr, Orgnr = A.orgnr, Månad = A.Manad, Intrastat =
A.varde,Moms = B.vardeutf
into #Tabell1
From
IntrastatFsum A
left outer join
Momsuppg B
on A.Orgnr = B.Orgnr
AND A.Manad = B.Manad
AND A.AR = B.Ar
where A.Orgnr in(
165563137933,165020456017,.......)
AND A.Ar = 2017
AND A.Manad = 9
AND A.InfUtf = 'U'

Related

T-SQL Full Outer Join (sample provided)

I have some issues getting a full outer join to work in T-SQL. The left outer join part seems to be working okay, but the right outer join doesn't work as expected. Here's some sample data to test this on:
I have a table A with the following columns and data. The row marked with red is the row that cannot be found in table B.
And a second table B with the following columns and data. The rows marked with yellow are the rows that cannot be found in table A.
I am trying to join the tables using the following sql code:
select tableA.klientnr, tableA.uttakstype, tableA.uttaksnr, tableA.vareanr TableAItem,tableB.vareanr tableBitem, tableA.kvantum tableAquantity, tableB.totkvant tableBquantity
from tableA as tableA
full outer join tableB as tableB on tableA.klientnr=tableB.klientnr and tableA.uttakstype=tableB.uttakstype and tableA.uttaksnr=tableB.uttaksnr and tableA.vareanr=tableB.vareanr and tableB.IsDeleted=0
where tableA.UttaksNr=639779 and tableA.IsDeleted=0
The result of the sql is the following image. The row marked in red is the extra row from tableA that does show up, but I can't get the rows from table B to show up
Expected to have 2 extra rows
550 SA 639779 NULL 100059 NULL 0
550 SA 639779 NULL 103040 NULL 14
Later edit:
Would this be correct way to handle the full outer join where there's the header/line type of structure? Or can the query be optimized?
SELECT ISNULL(q1.accountid, q2.accountid) AccountId
,ISNULL(q1.klientnr, q2.klientnr) KlientNr
,ISNULL(q1.tilgangstype, q2.tilgangstype) 'Reception Type'
,ISNULL(q1.tilgangsnr, q2.tilgangsnr) 'Reception No'
,ISNULL(q1.dato, q2.dato) dato
,ISNULL(q1.LevNr, q2.LevNr) LevNr
,ISNULL(q1.Pakkemerke, q2.Pakkemerke) Pakkemerke
,ISNULL(q1.VareANr, q2.VareANr) VareANr
,ISNULL(q1.Ankomstdato,q2.Ankomstdato) 'Arrival Date'
,q1.Antall1
,q1.totkvant1
,q1.Antall2
,q1.totkvant2
,q2.Antall
,q2.totkvant
,q2.AntallTilFrys
,q2.TotKvantTilFrys
,ISNULL(q1.EksternKommentar1,q2.EksternKommentar1) EksternKommentar1
,q2.[Last Upsert]
FROM (
SELECT w700.accountid
,w700.klientnr
,w700.tilgangstype
,w700.tilgangsnr
,w700.dato
,w700.Ankomstdato
,w700.LevNr
,w700.pakkemerke
,w789.VareANr
,sum(IIF(w789.prognosetype = 1, w789.Antall, NULL)) AS Antall1
,sum(IIF(w789.prognosetype = 1, w789.totkvant, NULL)) AS totkvant1
,sum(IIF(w789.prognosetype = 2, w789.Antall, NULL)) AS Antall2
,sum(IIF(w789.prognosetype = 2, w789.totkvant, NULL)) AS totkvant2
,w700.EksternKommentar1
FROM trading.W789Prognosekjopstat AS w789
INNER JOIN trading.W700Tilgangshode AS w700 ON w700.AccountId = w789.AccountId
AND w700.KlientNr = w789.Klientnr
AND w700.Tilgangsnr = w789.Tilgangsnr
AND w700.Tilgangstype = w789.Tilgangstype
AND w700.IsDeleted = 0
WHERE w789.IsDeleted = 0
GROUP BY w700.accountid
,w700.klientnr
,w700.tilgangstype
,w700.tilgangsnr
,w700.dato
,w700.Ankomstdato
,w700.LevNr
,w700.pakkemerke
,w789.VareANr
,w700.EksternKommentar1
) q1
FULL OUTER JOIN (
SELECT w700.accountid
,w700.klientnr
,w700.tilgangstype
,w700.tilgangsnr
,w700.dato
,w700.Ankomstdato
,w700.LevNr
,w700.pakkemerke
,w702.VareANr
,w702.Antall
,w702.TotKvant
,w702.ValPris
,w702.AntallTilFrys
,w702.TotKvantTilFrys
,w700.EksternKommentar1
,(SELECT MAX(LastUpdateDate) FROM (VALUES (w702.createdAt),(w702.updatedAt)) AS UpdateDate(LastUpdateDate)) AS 'Last Upsert'
FROM trading.w702PrognoseKjop w702
INNER JOIN trading.W700Tilgangshode AS w700 ON w700.AccountId = w702.AccountId
AND w700.KlientNr = w702.Klientnr
AND w700.Tilgangsnr = w702.Tilgangsnr
AND w700.Tilgangstype = w702.Tilgangstype
AND w700.IsDeleted = 0
WHERE w702.IsDeleted = 0
) q2 ON q1.accountid = q2.accountid
AND q1.klientnr = q2.klientnr
AND q1.tilgangstype = q2.tilgangstype
AND q1.tilgangsnr = q2.tilgangsnr
AND q1.vareanr = q2.vareanr
WHERE totkvant1 IS NOT NULL
OR totkvant2 IS NOT NULL
OR totkvant IS NOT NULL
Filtering with full join is really tricky. Your where criteria are actually turning the full join into a left join.
You can do what you want by filtering before the join:
select a.klientnr, a.uttakstype, a.uttaksnr, a.vareanr a.tableAitem,
b.vareanr b.tableBitem, a.kvantum a.tableAquantity, b.totkvant b.tableBquantity
from (select a.*
from tableA a
where a.UttaksNr = 639779 and a.IsDeleted = 0
) a full join
(select b.*
from tableB b
where b.IsDeleted = 0
) b
on a.klientnr = b.klientnr and
a.uttakstype= b.uttakstype and
a.uttaksnr = b.uttaksnr and
a.vareanr = b.vareanr;

How to get fields from multiple tables

I want to get fields from 2 different tables . The last field candidate_score_id has a many to one relationship. So how should I join the below 2 queries
1) To get candidate_score_id from the candidate_score table.
select candidate_score_id from candidate_score a where
a.assessment_id = NEW.assessment_id and
a.candidate_id = NEW.candidate_id and
a.attempt_Count = NEW.attempt_count;
2) To insert different fields in to the candidate_score_details table. The field in this table should be obtained by query above.
insert into candidate_score_details(candidate_score_details_id, candidate_id, assessment_id, attempt_count, score_type, score_tag,correct, candidate_score_id)
select uuid();
select a.candidate_id, a.assessment_id,a.attempt_count,"BY-COMPLEXITY",
case c.complexity
when 1 then "HIGH"
when 2 then "MEDIUM"
when 3 then "LOW"
end, count(*) from candidate_answer a, answer_key b, question_meta_data c where a.candidate_id = NEW.candidate_id and
a.assessment_id = NEW.assessment_id and
a.attempt_count = NEW.attempt_count and
a.assessment_id = b.assessment_id and
a.question_id = b.question_number and
a.response = b.answer and
a.question_id = c.question_number
group by a.candidate_id, a.assessment_id, a.attempt_count, c.complexity;
Just looking at the SQL joining aspect of your question, you'll need to specify the table I THINK you're aliasing a 2nd table with the "NEW" reference. If that's the case, then the query would be (replacing "OTHER_TABLE_NAME" with the name of the 2nd table:
select a.candidate_score_id
from candidate_score a
left join OTHER_TABLE_NAME new on
and a.assessment_id = NEW.assessment_id
and a.candidate_id = NEW.candidate_id
and a.attempt_Count = NEW.attempt_count
Seems that Query 1 has the same 3 criteria on the "candidate_score" table as for the "candidate_answer" table in Query 2.
So how about adding a LEFT JOIN of "candidate_score" to "candidate_answer" on those 3 fields?
For example:
INSERT INTO candidate_score_details
(
candidate_score_details_id,
candidate_id,
assessment_id,
attempt_count,
score_type,
score_tag,
correct,
candidate_score_id
)
SELECT
uuid(),
answer.candidate_id,
answer.assessment_id,
answer.attempt_count,
'BY-COMPLEXITY' AS score_type,
(CASE meta.complexity
WHEN 1 THEN 'HIGH'
WHEN 2 THEN 'MEDIUM'
WHEN 3 THEN 'LOW'
END) AS score_tag,
COUNT(*) AS correct,
MAX(score.candidate_score_id) AS max_candidate_score_id
FROM candidate_answer AS answer
JOIN answer_key AS akey
ON (akey.assessment_id = answer.assessment_id AND akey.question_number = answer.question_id AND akey.answer = answer.response)
LEFT JOIN candidate_score AS score
ON (score.candidate_id = answer.candidate_id AND score.assessment_id = answer.assessment_id AND score.attempt_count = answer.attempt_count)
LEFT JOIN question_meta_data AS meta
ON meta.question_number = answer.question_id
WHERE answer.candidate_id = NEW.candidate_id
AND answer.assessment_id = NEW.assessment_id
AND answer.attempt_count = NEW.attempt_count
GROUP BY answer.candidate_id, answer.assessment_id, answer.attempt_count, meta.complexity;

Why different results to two different ways of writing query

I am trying to understand why the following two SQL statements give different results. The first works as expected, the second produces no records.
Select * from Jet.LayoutListItemEntity_Default itemDefault
Join Jet.LayoutListEntity b
on itemDefault.UiKey = b.UiKey
Left join (Select * from Jet.LayoutListItemEntity where DomainId =2) item
on itemDefault.BindingPath = item.BindingPath
where item.DomainId is null
and b.DomainId = 2
Select * from Jet.LayoutListItemEntity_Default itemDefault
Join Jet.LayoutListEntity b
on itemDefault.UiKey = b.UiKey
Left join Jet.LayoutListItemEntity item
on itemDefault.BindingPath = item.BindingPath
where item.DomainId is null
and item.DomainId = 2
and b.DomainId = 2
The primary difference is that one puts the item.DomainId = 2 at the end, instead of in it's own select. It seems to me they would produce the same results.
Greg
These conditions are mutually exclusive:
where item.DomainId is null
and item.DomainId = 2
item.DomainID can't simultaneously be NULL and 2
You can move the errant where criteria to the JOIN criteria:
Select * from Jet.LayoutListItemEntity_Default itemDefault
Join Jet.LayoutListEntity b
on itemDefault.UiKey = b.UiKey
Left join Jet.LayoutListItemEntity item
on itemDefault.BindingPath = item.BindingPath
and item.DomainId = 2
where item.DomainId is null
and b.DomainId = 2
Your WHERE criteria is messed up in the 2nd query -- to make those statements the same, move the and item_DomainId = 2 to the JOIN.
Select * from Jet.LayoutListItemEntity_Default itemDefault
Join Jet.LayoutListEntity b
on itemDefault.UiKey = b.UiKey
Left join Jet.LayoutListItemEntity item
on itemDefault.BindingPath = item.BindingPath and item.DomainId = 2
where item.DomainId is null
and b.DomainId = 2

Speed up SQL query with nested query

I hope you guys can help me. I have the following SQL query, I think it's not very heavy but it takes about 5 minutes to complete. Please let me know if you have another way to complete this:
update rep
set rep.StatusID= 2,
rep.Available= 1,
rep.User= #user
from dbo.MCP_Rep_Compensation_Plan rep
left join dbo.MCP_Compensation_Plan compensationplan on compensationplan.Compensation_Plan_ID = #compplan_id and compensationplan.Active = 1
left join dbo.MRRS_Cycle actualcycle on actualcycle.CycleID = compensationplan.CycleID and actualcycle.Active = 1
left join dbo.MRRS_Cycle lastcycle on lastcycle.Consecutive = actualcycle.Consecutive -1 and lastcycle.Active = 1
where rep.Active = 1 and rep.ID_Compensation_Plan = #compplan_id and exists(
select OrderID
from dbo.MCP_Orders
where Active = 1 and Order_cycle = lastcycle.CycleID and OrderRepID = rep.RepID
and Order_Status in(28,30))
I do see some places your query can be rewritten, but I'm not sure how much it will help without looking at your execution plans and ensuring you have the appropriate indices in place.
For example, make sure you include actual join criteria in your first join to the compensationplan table. Do this by joining on compensationplan.Compensation_Plan_ID and rep.ID_Compensation_Plan.
Also, I don't see the need for the OUTER JOINs since you're using some of those tables in your correlated exist subquery.
Here is the updated query:
update rep
set rep.StatusID= 2,
rep.Available= 1,
rep.User= #user
from dbo.MCP_Rep_Compensation_Plan rep
join dbo.MCP_Compensation_Plan compensationplan on
compensationplan.Compensation_Plan_ID = rep.ID_Compensation_Plan and compensationplan.Active = 1
join dbo.MRRS_Cycle actualcycle on
actualcycle.CycleID = compensationplan.CycleID and actualcycle.Active = 1
join dbo.MRRS_Cycle lastcycle on
lastcycle.Consecutive = actualcycle.Consecutive -1 and lastcycle.Active = 1
where rep.Active = 1
and rep.ID_Compensation_Plan = #compplan_id
and exists(
select OrderID
from dbo.MCP_Orders
where Active = 1
and Order_cycle = lastcycle.CycleID
and OrderRepID = rep.RepID
and Order_Status in(28,30)
)

Need help on SELECT DISTINCT query

I'm using Firebird 2.1 to perform this query:
SELECT DISTINCT INVOICES.INVNO,INVOICES.DEPNO,INVOICES.INVN,INVOICES.CONTNO,SYSPROF.NAME
FROM INVOICES
LEFT JOIN INVSPEC ON (INVOICES.INVNO = INVSPEC.INVNO) AND (INVOICES.DEPNO = INVSPEC.DEPNO)
LEFT JOIN SYSPROF ON (INVSPEC.SYSNO = SYSPROF.SYSNO) WHERE
(INVOICES.INVNO = 17 AND INVOICES.DEPNO = 6555)
OR(INVOICES.INVNO = 16 AND INVOICES.DEPNO = 6555);
and it returns me these records:
Please help me to build a query that will return these records:
Thank you!
For instance:
SELECT INVOICES.INVNO,min(INVOICES.DEPNO),min(INVOICES.INVN),min(INVOICES.CONTNO),min(SYSPROF.NAME)
FROM INVOICES
LEFT JOIN INVSPEC ON (INVOICES.INVNO = INVSPEC.INVNO) AND (INVOICES.DEPNO = INVSPEC.DEPNO)
LEFT JOIN SYSPROF ON (INVSPEC.SYSNO = SYSPROF.SYSNO) WHERE
(INVOICES.INVNO = 17 AND INVOICES.DEPNO = 6555)
OR(INVOICES.INVNO = 16 AND INVOICES.DEPNO = 6555);
GROUP BY INVOICES.INVNO
This query returns one row per invoice and takes any name from the sysprof.