Permalänk
Medlem

SQL SELECT fråga?

Jag har problem (av okunskap) hur jag ska få med alla A.EmpNo i resultatet. Jag har 20st personer men om t.ex enbart 15 har rapporterat in tid så är resultatet enbart på dessa 15 och inte så att de övriga 5 får resultat 0. Är det någon som kan tipsa mig om hur jag löser detta?

select A.EmpNo 'ID' , COALESCE(A.Nm,'') 'Namn' , ROUND((SUM(CASE WHEN O.ProdNo = '804' THEN NoFin+NoInvoAb ELSE 0 END)/40)*100,0) 'Frånvaro %' , SUM(CASE WHEN P.Gr4 = '1' THEN NoFin+NoInvoAb ELSE 0 END) Antal , ROUND((SUM(CASE WHEN P.Gr4 = '1' THEN NoFin+NoInvoAb ELSE 0 END)/40)*100,0) 'Deb %' from actor A left outer join OrdLn O ON A.EmpNo = O.R1 inner join Prod P on O.ProdNo = P.ProdNo where A.R1 <= 990 AND A.R10 <> '' AND (P.Gr4 = 1 OR P.Gr = 1) AND O.R1 <> '' AND O.EmpNo <> '' AND TrDt >= CONVERT(int,CONVERT(varchar,DATEADD(wk, DATEDIFF(wk, 0, GETDATE()), 0),112)) group by A.EmpNo, A.Nm order by ID

Actor A

EmpNo R1 Nm 1 1 John Doe 2 2 Bertil Doe

Prod P

ProdNo Gr Gr4 100 1 1 110 1 0 200 1 1

OrdLn O

R1 EmpNo NoFin NoInvoAb TrDt 189 189 0.000000 1.000000 20180216 184 184 0.000000 2.000000 20180212 184 184 0.000000 7.000000 20180215 184 184 0.000000 5.000000 20180215 184 184 0.000000 40.000000 20180215 186 186 0.000000 0.500000 20180215

Permalänk
Hedersmedlem

Det kan vara enklare att förstå din frågeställning och att få hjälp om du:

1. Kapslar in din kod mellan [code] och [/code] (så att det är lättare att läsa din kod i inlägget).

2. Tar med några rader exempeldata som visar strukturen som ditt data har.

Förenkla gärna frågeställningen genom att förenkla ditt data och din SQL-fråga till den grad att ditt problem fortfarande uppstår, men att du inte behöver förklara halva din applikation.

Permalänk
Medlem

Har du satt defaultvärde på cellen som lagrar tid? Annars får du ju null där.

Permalänk
Medlem

@pv2b: Tack för snabbt svar. Blev det enklare eller ska jag fylla på med mer information?

Permalänk
Hedersmedlem
Permalänk
Medlem

Eftersom du efterfrågade tips så är mitt tips att tänka efter vad dina två join gör steg för steg:

from actor A left outer join OrdLn O ON A.EmpNo = O.R1

Vad ger denna för värde på alla fält tillhörande OrdLn när det inte finns någon matchande post i OrdLn?
Vad händer då när nästa join är en inner join?

inner join Prod P on O.ProdNo = P.ProdNo

Permalänk
Medlem

@pv2b: Sorry, nu är även OrdLn med.

Permalänk
Medlem

@johho: Jo jag vet att jag kanske är helt fel på det här. Ser du vad jag göra fel? Finns det bra guider för att plugga på just JOIN så man inte som jag chansar rätt ofta?

Permalänk
Medlem

@BoEl: Det var inte min mening ge dig intrycket att du är helt fel på det här, men eftersom du efterfrågade tips och inte lösningen försökte jag med frågor styra dig rätt till lösningen istället för att bara skriva den.

När du gör flera joins efter varandra kommer den logiska evalueringen att ske i den ordning de är skrivna. Lösningen är att se till att din inner join mellan OrdLn och Prod logiskt evalueras före din outer join med actor.

För en utförlig förklaring: Be Careful When Mixing INNER and OUTER Joins

from actor A left outer join (OrdLn O inner join Prod P on O.ProdNo = P.ProdNo) ON A.EmpNo = O.R1

Det jag tror skulle lösa ditt problem (med reservation för SQL-dialekt och att inget är provkört)
Permalänk
Medlem

@johho: Ok tack men jag ser tyvärr inte hur jag ska kunna join:a Prod innan jag har join:at OrdLn. Då dessa ska join:a varandra.

Är problemet just att jag inte har en gemensam nämnare i Actor? Utan det är OrdLn som är den gemensamma som alla kan join:a emot? Men kommer jag kunna få resultatet att jag vill ha alla Actor oavsett om det inte finns några OrdLn rader som passar den eller inte?

Permalänk
Medlem

Annars kan du ju bara ändra i tabellen.

om inget är angivet så blir det en 0 i tabellen.

settings för tabellen:

Det är "ZF" du ska markera och tror du behöver ha typen som int också.

Visa signatur

i5-12600KF | Noctua NH-D15S Chromax Black | MSI MAG B660M | 64 GB G.Skill Trident Z | 3 * WD Black SN750 | Asus TUF OC RTX 3080 | Fractal Design Torrent | Corsair RM750W | Samsung Odyssey G9 49" |

Permalänk
Avstängd

Du behöver inte skriva ut OUTER eller INNER utan det är liksom underförstått, blir kanske tydligare om man inte har så bra koll dock. Men i alla fall så får du med en left (outer) join med alla rader i den vänstra tabellen och med en (inner) join så får du bara med de rader som finns i båda tabellerna. Så om du exempelvis har en tabell a som har data om personer och tabell b som har data om deras barn. Skriver du left (outer) join från a till b så får du med även personer utan barn, alltså utan någon post i tabell b. Skriver du istället (inner) join så får du bara med personer som har barn (eller en post i tabell b). Har du sen en tabell till, kanske c, med data om barnen och gör en (inner) join mot den så får du inte med de från a och b som inte har en motsvarande post i c utan du måste göra left joins hela vägen om du vill få med alla som finns i a.

Permalänk
Medlem

@BoEl: Så den kodsnutt jag skrev i mitt föregående inlägg fungerar inte?