Sql query with 4 tables - sql

I have 4 tables: Fonctionnaire, Echelon, PromotionEchelon, Mise.
Fonctionnaire: CodeFonctionnaire(PK), NomFonctionnaire, PrenomFonctionnaire
Echelon : NumEchelon(PK), CodeEchelon, Indice
PromotionEchelon:CodeFonctionnaire(FK),NumEchelon(FK),DateArrete
Mise:CodeMise(PK),Nature,NumArrete,DateArrete,DureeMise,CodeFonctionnaire(FK)
I want to select the list of all 'Fonctionnaire' and their 'DateArrete' from
'PromotionEchelon' and their 'CodeEchelon, Indice' from 'Echelon' and if
exist their 'Nature,NumArrete,DateArrete,DureeMise' from 'Mise'.
I used this query:
SELECT
Fonctionnaire.CodeFonctionnaire,
Fonctionnaire.NomFonctionnaire,
Fonctionnaire.PrenomFonctionnaire,
Echelon.CodeEchelon, Echelon.Indice,
PromotionEchelon.DateArrete,
Mise.Nature, Mise.NumArrete, Mise.DateArrete, Mise.DureeMise
FROM
Fonctionnaire, PromotionEchelon, Echelon, Mise
WHERE
Fonctionnaire.CodeFonctionnaire = PromotionEchelon.CodeFonctionnaire
AND PromotionEchelon.NumEchelon = Echelon.NumEchelon
AND Fonctionnaire.CodeFonctionnaire = Mise.CodeFonctionnaire
But it returns 0 records, i tried inner and outer join and i get errors.
So where is the error in my query?

You do not address the JOIN chain properly
Start with the following and see what you get
SELECT
Fonctionnaire.CodeFonctionnaire
, Fonctionnaire.NomFonctionnaire
, Fonctionnaire.PrenomFonctionnaire
, Echelon.CodeEchelon, Echelon.Indice
, PromotionEchelon.DateArrete
,Mise.Nature, Mise.NumArrete, Mise.DateArrete, Mise.DureeMise
FROM
Fonctionnaire f
LEFT JOIN PromotionEchelon p
ON p.CodeFonctionnaire = f.CodeFonctionnaire
LEFT JOIN Mise m
ON m.CodeFonctionnaire = f.CodeFonctionnaire
LEFT JOIN Echelon e
ON e.NumEchelon = p.NumEchelon

Related

Print more than 2 tables in SQL

I want to print out 2 or more tables in the SQL azure, but i'm trying to using UNION and UNION ALL but it still have the same error which is
Msg 205, Level 16, State 1, Procedure Query12, Line 7
All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists
GO
CREATE PROCEDURE Query12
#date_job_completed varchar(50),
#Department_number int
AS
BEGIN
With q as(
SELECT Job.Job_no, type_of_machine_use, amount_of_time_machine_use, martirial_used, labor_time, date_job_completed as Print_out
FROM Cut_job
INNER JOIN Job ON Job.Job_no = Cut_job.Job_no
INNER JOIN No_of_Process ON No_of_Process.Process_id = Job.Process_id
INNER JOIN Department ON Department.Department_number = No_of_Process.Department_number
WHERE Cut_job.date_job_completed = #date_job_completed AND Department.Department_number = #Department_number
UNION ALL
SELECT Job.Job_no, Color, Volume, labor_time, date_job_completed as Print_out
FROM Paint_job
INNER JOIN Job ON Job.Job_no = Paint_job.Job_no
INNER JOIN No_of_Process ON No_of_Process.Process_id = Job.Process_id
INNER JOIN Department ON Department.Department_number = No_of_Process.Department_number
WHERE Paint_job.date_job_completed = #date_job_completed AND Department.Department_number = #Department_number
UNION ALL
SELECT Job.Job_no, labor_time, date_job_completed as Print_out
FROM Fit_job
INNER JOIN Job ON Job.Job_no = Fit_job.Job_no
INNER JOIN No_of_Process ON No_of_Process.Process_id = Job.Process_id
INNER JOIN Department ON Department.Department_number = No_of_Process.Department_number
WHERE Fit_job.date_job_completed = #date_job_completed AND Department.Department_number = #Department_number
)
SELECT Print_out
FROM q
END
GO
EXEC Query12 #date_job_completed = '23/23/2019', #Department_number = 4;
The basic rule for combining the result set of two or more queries by using UNION, UINON ALL, EXCEPT or INTERSECT are:
The number and order of the columns in the query must be same
And the data types should be compatible.
If this is not followed you will encounter the error as below.
If you do not have the same column list in all queries to avoid the errors, you can add NULL columns to the missing column list as below.

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;

Get part of the result into columns instead of lines

I have a query about internal and external trainings. Every training has 1 or more speakers. What I want is to have a column for every speaker.
I was checking on aggregate functions, but I couldn't find the one solving my problem.
select e.sid
, e.access_kz EXTERN1
, z.zuname VERTRETERPERSONAL1
from MDEV e
join MDEVCAL ec on (ec.klient_id = e.klient_id and ec.EV_sid = e.sid)
left outer join MDEVCALS ecs on (ecs.klient_id = e.klient_id and ecs.ev_sid = e.sid and ecs.evcal_sid = ec.sid)
left outer join MDZHD z on (z.klient_id = e.klient_id and z.sid = ecs.MDZHD_SID)
I use left outer joins because a training doesn't have to have a speaker but can have X different speakers
What I want to have is something like this:
SID | Extern1 | VERTRETERPERSONAL1 | VERTRETERPERSONAL2 | VERTRETERPERSONAL3 ...
I think the Following query will resolve your problem but with the static list of trainers.
SELECT
*
FROM
(
SELECT
E.SID,
E.ACCESS_KZ EXTERN1,
Z.ZUNAME VERTRETERPERSONAL
FROM
MDEV E
JOIN MDEVCAL EC ON ( EC.KLIENT_ID = E.KLIENT_ID
AND EC.EV_SID = E.SID )
LEFT OUTER JOIN MDEVCALS ECS ON ( ECS.KLIENT_ID = E.KLIENT_ID
AND ECS.EV_SID = E.SID
AND ECS.EVCAL_SID = EC.SID )
LEFT OUTER JOIN MDZHD Z ON ( Z.KLIENT_ID = E.KLIENT_ID
AND Z.SID = ECS.MDZHD_SID )
) PIVOT (
MAX ( VERTRETERPERSONAL )
FOR VERTRETERPERSONAL
IN ( '<VERTRETERPERSONAL_NAME1>' AS VERTRETERPERSONAL1, '<VERTRETERPERSONAL_NAME2>' AS VERTRETERPERSONAL2, .... )
);
Cheers!!

Joining 2 columns where 1 column has unique records and the other has duplicates

I have 2 column Risk_Geo_ID in one table which has duplicates and Geography_Identifier in other table which has unique records. Doing an inner join is giving me duplicate records and cannot process this query in cube as Geography_Identifier is a PK and its unique. Need a query to get unique records.
Here is the Code:
SELECT
s.Geography_Identifier
,s.State_Code
,s.State_Name
,s.County_Name
,s.City_Name
,s.ZIP_Code
,a.Risk_ID
,a.Risk_Address
,a.Latitude
,a.Longitude
,a.Distance_to_Coast
,a.Insurance_Score
FROM [Policy].[Dim_Risk] AS a
INNER JOIN [Policy].[Fact_Monthly_Policy_Snap] AS b
ON b.Risk_ID = a.Risk_ID
AND b.Insurance_score = a.Insurance_Score
INNER JOIN [Common].[Dim_Geography] AS s
ON b.Risk_Geo_ID = s.Geography_Identifier
Try using the distinct
SELECT
distinct s.Geography_Identifier
,s.State_Code
,s.State_Name
,s.County_Name
,s.City_Name
,s.ZIP_Code
,a.Risk_ID
,a.Risk_Address
,a.Latitude
,a.Longitude
,a.Distance_to_Coast
,a.Insurance_Score
FROM [Policy].[Dim_Risk] AS a
INNER JOIN [Policy].[Fact_Monthly_Policy_Snap] AS b
ON b.Risk_ID = a.Risk_ID
AND b.Insurance_score = a.Insurance_Score
INNER JOIN [Common].[Dim_Geography] AS s
ON b.Risk_Geo_ID = s.Geography_Identifier
Try to use CROSS APPLY with TOP 1 if you want to get just one row with such ID:
SELECT
q.Geography_Identifier
,s.State_Code
,s.State_Name
,s.County_Name
,s.City_Name
,s.ZIP_Code
,a.Risk_ID
,a.Risk_Address
,a.Latitude
,a.Longitude
,a.Distance_to_Coast
,a.Insurance_Score
FROM [Policy].[Dim_Risk] AS a
INNER JOIN [Policy].[Fact_Monthly_Policy_Snap] AS b
ON b.Risk_ID = a.Risk_ID
AND b.Insurance_score = a.Insurance_Score
CROSS APPLY
(
SELECT
TOP 1
*
FROM [Common].[Dim_Geography] AS s
WHERE s.Geography_Identifier = b.Risk_Geo_ID
)q

Two select statements turn into one

I have set of two queries. In first query, if is separate from second, I got good results.
First query
SELECT *
FROM
(
SELECT nks.[Id]
, nks.[IdNarudzbe]
, nks.[IdArtikla] as artikal
, nks.[IdUsluge]
, nks.[Naziv]
, nks.Kolicina
, p.Naziv as kupac
, p.Id as kupacId
, p.Adresa
, p.Telefon
, nkz.[BrojDokumenta] AS nalog
, nkz.[BrojDokumentaKroz] AS nalogKroz
, nkz.[RokIsporuke]
, nkz.[IdNastaloOdDokumenta]
, d.Naziv as drzava
FROM [dbo].[NarudzbaKupacaStavke] nks
LEFT JOIN [dbo].[NarudzbeKupacaZaglavlje] nkz
ON nkz.Id = nks.IdNarudzbe
LEFT JOIN dbo.Partneri p
ON nkz.IdKupac = p.Id
LEFT JOIN dbo.Drzave d
ON p.IdDrzava = d.Id
WHERE idArtikla IN ('FP80PUR-08', 'FP80PUR-09', 'FP80PUR-12')
AND nkz.[VrstaDokumenta] = 'PRO'
AND nkz.StatusArhive = 0
--...
from first query nkz.[IdNastaloOdDokumenta] is important to second
SELECT BrojDokumenta
, BrojDokumentaKroz
FROM .[dbo].[NarudzbeKupacaZaglavlje]
where id = nkz.[IdNastaloOdDokumenta]
For ex. In first query I got nkz.[IdNastaloOdDokumenta] = 20. Number 20 I use in second query in where statement, and value I get from BrojDokumenta, I would like to join to first query.
I was wondering if is possible to make one query out of these two. I think I can not union operator because number of column from these two queries don't match.
The same table, and the same columns are already in the first query. Perhaps you want a self-join, like this:
FROM [dbo].[NarudzbaKupacaStavke] nks
LEFT JOIN [dbo].[NarudzbeKupacaZaglavlje] nkz
ON nkz.Id = nks.IdNarudzbe
LEFT JOIN [dbo].[NarudzbeKupacaZaglavlje] nkz2
ON nkz2.Id = nkz.[IdNastaloOdDokumenta]
LEFT JOIN dbo.Partneri p
ON nkz.IdKupac = p.Id
LEFT JOIN dbo.Drzave d
ON p.IdDrzava = d.Id
WHERE idArtikla IN ('FP80PUR-08', 'FP80PUR-09', 'FP80PUR-12')
AND nkz.[VrstaDokumenta] = 'PRO'
AND nkz.StatusArhive = 0