Vinnaren i pepparkakshustävlingen!
2011-10-14, 23:37
  #37
Medlem
gadzooxs avatar
Citat:
Ursprungligen postat av SorXisteN
Tack! Det hjälper verkligen när ni förklarar

Jag har en fråga som jag ställt tidigare som kan är lite ja..smått dum :P men iaf, det finns som sagt olika typer av JOINS, t.ex. LEFT JOIN från den vänstra tabellen osv. Men hur vet man i vilken ordning (vänster -> höger) som tabellerna är? Det måste väl sitta i uppbyggnaden i tabellen, bestämmer man då nån viss "position" på den? Hänger inte riktigt med där
LEFT JOIN vs RIGHT JOIN vs INNER JOIN syftar på hur datat från de bägge tabellerna joinas ihop, inte "i vilken ordning de är" eller hur de är uppbyggda.

Wikipedialänken Proton postade beskriver det hela mycket bra med fina exempel, men för att recappa lite:
Citat:
The result of a left outer join (or simply left join) for table A and B always contains all records of the "left" table (A), even if the join-condition does not find any matching record in the "right" table (B). This means that if the ON clause matches 0 (zero) records in B, the join will still return a row in the result—but with NULL in each column from B. This means that a left outer join returns all the values from the left table, plus matched values from the right table (or NULL in case of no matching join predicate).
A och B syftar alltså på:

SELECT A.*, B.*
FROM A LEFT JOIN B ON A.id = B.id


Motsvarande gäller för RIGHT JOIN, där all data från den högra tabellen (dvs den tabell man angett till höger om nyckelordet JOIN) kommer med i resultatet, medan nullvärden kan förekomma för de rader där predikatet inte matchar någon post i den vänstra tabellen.

Med INNER JOIN eliminerar du nullvärden ur resultatet, det måste finnas en matchande rad i den joinade tabellen.
Citera
2011-10-15, 01:20
  #38
Medlem
Citat:
Ursprungligen postat av Proton
Inte riktigt...

Om du tänker dej hur du skriver ett matematiskt uttryck, exempelvis något så simpelt som 1 * 2 så har du ju vänster respektive höger operand och i mitten har du en operator.

Detsamma gäller för databastabeller, eller snarare hur de betraktas, dvs som mängder. Mängder kan man även utföra diverse operationer på, till exempel JOIN, UNION, INTERSECT etc på, relationsalgebran behandlar dessa operationer och utfallen av dem:

http://en.wikipedia.org/wiki/Relational_algebra

För att göra en lång historia kort så är alltså vänster tabell den tabellen som står till vänster om din mängdoperator (dvs JOIN, UNION, INTERSECT, EXCEPT etc) och höger tabell är följdaktligen den tabellen som finns till höger om mängdoperatorn.

Förstog du?


Ja hyffsat Måste så klart plugga på det lite för att det ska sitta mer men jag är som sagt helt ny inom SQL sedan 3-4 dagar tillbaka men tycker det verkar grymt kul o intressant när det fungerar som jag vill haha
Citera
2011-10-15, 02:12
  #39
Medlem
All hjälp till trots, så sitter jag här och trocklar igen. 02 på en fredag :P Jag får inte ihop det (ännu än gång) förstår om ni tröttnar lite men all er hjälp är guld värd

http://cdn.imghack.se/images/2384fa1...0d844a7186.jpg

FRÅGA: A10

Mina försök ser ni brevid. På ena får jag alltså ut average Lönen men inte med tillhörande avdelningar, och på de andra är det bara, kajko..

Provade även med
Kod:
select Namn from avdelning
where avdid in 
(
select avdid from anstalld 
where Anstalld
.lon '23000'

Då fick jag fram avdelningar som hade anställda med lön över 23000. Ser på vissa felmeddelanden att jag ska använda HAVING ist. för WHERE så satte mig o läste lite om HAVING men fick det fortf. inte o fungera (http://www.w3schools.com/sql/sql_having.asp)

Mitt största problem som det känns just nu för att komma vidare är att jag fattar inte riktigt hur jag ska skriva för att baka in fler frågor i samma fråga. När jag ser kod som ni ger mig så förstår jag den, men förstår inte själv hur jag ska skriva.

Ett exempel:

Kod:
select NamnLon from ANSTALLD
where Avdid
='AVD03' 

Och

Kod:
select NamnLon from ANSTALLD
where Avdid
='AVD02' 

Hur bakar jag inte dessa två frågor i samma? Jag har bara två olika värden men vet inte hur jag ska skriva det. Provade med t.ex.

Kod:
select NamnLon from ANSTALLD
where Avdid
='AVD02''AVD03' 

Eller lägga till AND lr OR mellan, men kände på mig att det inte skulle funka men prova dock.

Lika kul som det är att sitta o skriva frågor o lyckas, lika frusterande är det att misslyckas.
Citera
2011-10-15, 08:38
  #40
Medlem
Lite osäker men det här skulle kanske kunna fungera med lite modifikation!

Börja med att kolla på det som står i subselecten i from, där hämtar vi avdelningsnamnen, medellönen för varje avdelning genom att gruppera på avdelning. Den översta selecten hämtar från det som finns i subselecten, möjligt i detta fall är AvdelningsNamn och Average. Frågan avslutas med att bara ta med de avdelningar som har en medellön över 23000. Du kan lägga till Average i selecten längst upp om du vill för att säkerställa att inga andra kommer med!


Kod:
select AvdelningsNamn
from (
	select av.Namn as AvdelningsNamn
	AVG(a.Lon) as Average  
	from Avdelning av
	join Anstalld a on a.Avdid = av.Avdid
	group by av.Namn
	) hej
	where Average > 23000
Citera
2011-10-15, 08:56
  #41
Moderator
Protons avatar
Citat:
Ursprungligen postat av SorXisteN
All hjälp till trots, så sitter jag här och trocklar igen. 02 på en fredag :P Jag får inte ihop det (ännu än gång) förstår om ni tröttnar lite men all er hjälp är guld värd

http://cdn.imghack.se/images/2384fa1...0d844a7186.jpg

FRÅGA: A10

Mina försök ser ni brevid. På ena får jag alltså ut average Lönen men inte med tillhörande avdelningar, och på de andra är det bara, kajko..

Provade även med
Kod:
select Namn from avdelning
where avdid in 
(
select avdid from anstalld 
where Anstalld
.lon '23000'

Då fick jag fram avdelningar som hade anställda med lön över 23000. Ser på vissa felmeddelanden att jag ska använda HAVING ist. för WHERE så satte mig o läste lite om HAVING men fick det fortf. inte o fungera (http://www.w3schools.com/sql/sql_having.asp)

Mitt största problem som det känns just nu för att komma vidare är att jag fattar inte riktigt hur jag ska skriva för att baka in fler frågor i samma fråga. När jag ser kod som ni ger mig så förstår jag den, men förstår inte själv hur jag ska skriva.

Ett exempel:

Kod:
select NamnLon from ANSTALLD
where Avdid
='AVD03' 

Och

Kod:
select NamnLon from ANSTALLD
where Avdid
='AVD02' 

Hur bakar jag inte dessa två frågor i samma? Jag har bara två olika värden men vet inte hur jag ska skriva det. Provade med t.ex.

Kod:
select NamnLon from ANSTALLD
where Avdid
='AVD02''AVD03' 

Eller lägga till AND lr OR mellan, men kände på mig att det inte skulle funka men prova dock.

Lika kul som det är att sitta o skriva frågor o lyckas, lika frusterande är det att misslyckas.
Kolla på felmeddelandet du får från databasen är ju det första tricket till att lösa problemet.

"Ambiguos" betyder "tvetydig" och tvetydigheter är inte något en databas är bra på att hantera. I det här fallet är det Namn i din select som ställer till det. Namn finns i både avdelningstabelllen och i anstäldtabelllen som du JOINar ihop, därför kommer det i det slutgiltiga sökresultatet databasen har att leta i finnas 2 stycken kolumner med namn, men du säger bara att du vill ha ut ett namn, vilket som helst, men det funkar inte för en dator som måste få reda på precis vilket namn du avser.

I det här fallet var det avdelningen du var ute efter, så hade du skrivit
Kod:
SELECT av.namn FROM... 
hade din fråga troligen exekverat och gett dej något form av svar.
Citera
2011-10-15, 13:58
  #42
Medlem
Citat:
Ursprungligen postat av Proton
Kolla på felmeddelandet du får från databasen är ju det första tricket till att lösa problemet.

"Ambiguos" betyder "tvetydig" och tvetydigheter är inte något en databas är bra på att hantera. I det här fallet är det Namn i din select som ställer till det. Namn finns i både avdelningstabelllen och i anstäldtabelllen som du JOINar ihop, därför kommer det i det slutgiltiga sökresultatet databasen har att leta i finnas 2 stycken kolumner med namn, men du säger bara att du vill ha ut ett namn, vilket som helst, men det funkar inte för en dator som måste få reda på precis vilket namn du avser.

I det här fallet var det avdelningen du var ute efter, så hade du skrivit
Kod:
SELECT av.namn FROM... 
hade din fråga troligen exekverat och gett dej något form av svar.


Jag försöker o titta o klura via felmeddelandet, därför ja satt o trockla till 02 innan jag posta här Jag tror jag måste försöka vara lite mer specifik och vara noga med vissa tecken etc.
Citera
2011-10-15, 15:25
  #43
Medlem
Om jag har en tabell (Projekt) där ett Namn kopplas ihop med ett projekt. Vilken WHERE funktion använder jag då för att få ut vem som är med i alla projekt?

Har försökt med

Where Namn > '3' men det va mest ett desperat hopp och jag fick istället upp alla namn. Provade även med Having men kunde ej hitta rätt aggregate funktion så antar att det också är fel
Citera
2011-10-15, 17:36
  #44
Moderator
Protons avatar
Citat:
Ursprungligen postat av SorXisteN
Om jag har en tabell (Projekt) där ett Namn kopplas ihop med ett projekt. Vilken WHERE funktion använder jag då för att få ut vem som är med i alla projekt?

Har försökt med

Where Namn > '3' men det va mest ett desperat hopp och jag fick istället upp alla namn. Provade även med Having men kunde ej hitta rätt aggregate funktion så antar att det också är fel
Ett sätt att lösa detta problem på är att, beroende på hur frågan ställs, LEFT eller RIGHT JOINa ihop användare med projekttabellen och sedan plocka bort det som har NULL som id.

Ett annat aningen mer basic sätt att lösa det hela på när du vill kontrollera fler förekomster än bara en är att använda WHERE-vilkoret IN.

Kod:
SELECT from someTable where someAttribute IN(1,2,3)
SELECT FROM someTable WHERE someAttribute IN(SELECT anotherAttribute FROM anotherTable
Citera
2011-10-16, 14:30
  #45
Medlem
Citat:
Ursprungligen postat av Proton
Ett sätt att lösa detta problem på är att, beroende på hur frågan ställs, LEFT eller RIGHT JOINa ihop användare med projekttabellen och sedan plocka bort det som har NULL som id.

Ett annat aningen mer basic sätt att lösa det hela på när du vill kontrollera fler förekomster än bara en är att använda WHERE-vilkoret IN.

Kod:
SELECT from someTable where someAttribute IN(1,2,3)
SELECT FROM someTable WHERE someAttribute IN(SELECT anotherAttribute FROM anotherTable

Kod:
select a.Namn from Anstalld as a
where a
.aid IN
(
select ap.aid from anstproj as ap
where ap
.aid >= '2'

Och

Kod:
select a.Namn from Anstalld as a
INNER JOIN ANSTPROJ 
as ap on
a
.aid=ap.aid 
where ap
.aid >= '2'
GROUP BY Namn 

Blir samma svar (bara att namnen hamnar i olika ordning)

Frågan är A7: http://cdn.imghack.se/images/2384fa1...0d844a7186.jpg

Problemet jag har, är att jag får ihop tabellerna jag behöver få ihop, men villkoren för vad jag vill få fram stämmer inte. Det jag ville med > '2' är att jag trodde det skulle resultera i alla aid från anstproj som förekommer mer än 2 gånger (eller bara 2 gånger) men det ska skrivas på något annat sätt.
Citera
2011-10-16, 15:21
  #46
Moderator
Protons avatar
Citat:
Ursprungligen postat av SorXisteN
Kod:
select a.Namn from Anstalld as a
where a
.aid IN
(
select ap.aid from anstproj as ap
where ap
.aid >= '2'

Och

Kod:
select a.Namn from Anstalld as a
INNER JOIN ANSTPROJ 
as ap on
a
.aid=ap.aid 
where ap
.aid >= '2'
GROUP BY Namn 

Blir samma svar (bara att namnen hamnar i olika ordning)

Frågan är A7: http://cdn.imghack.se/images/2384fa1...0d844a7186.jpg

Problemet jag har, är att jag får ihop tabellerna jag behöver få ihop, men villkoren för vad jag vill få fram stämmer inte. Det jag ville med > '2' är att jag trodde det skulle resultera i alla aid från anstproj som förekommer mer än 2 gånger (eller bara 2 gånger) men det ska skrivas på något annat sätt.
aid större än 2 kommer göra precis vad det låter som. Den kommer filtrera ut alla som har anställningsnummer som är större än två. Killen med anställningsnummer 1 kommer inte komma med. Dessutom ställer jag mej tveksam till om databasen implicit kan konvertera från en sträng till en int rätt opp och ner, men det är en annan sak...

Det hela kommer troligen bli enklare för dej att lösa om du delar upp problemet i mindre delar. En lämplig approach kan vara att ta reda på vilket anställningsnummer den eller de har som är med i ett visst projekt. Hur gör du en sådan fråga?

När du har fått ut rätt svar på den frågan kan vi gå vidare med att ta reda på namnen som finns kopplade på dessa idn.

Hint: COUNT, GROUP BY och HAVING kommer troligen till användning här, men börja som sagt att endast ägna dej åt projekten och räkna samman dem.
Citera
2011-10-17, 13:47
  #47
Medlem
Citat:
Ursprungligen postat av Proton
aid större än 2 kommer göra precis vad det låter som. Den kommer filtrera ut alla som har anställningsnummer som är större än två. Killen med anställningsnummer 1 kommer inte komma med. Dessutom ställer jag mej tveksam till om databasen implicit kan konvertera från en sträng till en int rätt opp och ner, men det är en annan sak...

Det hela kommer troligen bli enklare för dej att lösa om du delar upp problemet i mindre delar. En lämplig approach kan vara att ta reda på vilket anställningsnummer den eller de har som är med i ett visst projekt. Hur gör du en sådan fråga?

När du har fått ut rätt svar på den frågan kan vi gå vidare med att ta reda på namnen som finns kopplade på dessa idn.

Hint: COUNT, GROUP BY och HAVING kommer troligen till användning här, men börja som sagt att endast ägna dej åt projekten och räkna samman dem.


Kod:
SELECT namn FROM anstalld 
WHERE aid IN 
(SELECT aid FROM anstproj
GROUP BY aid HAVING COUNT
(aid) > '2'

Nu har jag suttit ett tag och fått ut denna kod. Den ger mig rätt svar, man är inte nöjd. Jag undrar hur jag ska skriva detta, utan att veta att det finns just 3 projekt. Därav vet jag att > 2 ger mig rätt svar. Hade det annars varit 10 projekt så hade det kunnat ställa till problem.

Jag har även försökt skriva samma kod fast med JOIN istället:

Kod:
select Namn from anstalld
Join anstproj on
anstproj
.AID anstalld.AID
GROUP BY aid HAVING COUNT
(aid) > '2' 

Men får upp "Ambiguous field name between table ANSTALLD and table ANSTPROJ
AID". Alltså att det är tvetydigt "field name" mellan anstalld och anstproj AID. Läser om och om igen och provar med att ändra till GROUP BY anstproj.aid HAVING COUNT(anstproj.aid) > '2', men får då upp "Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause)".

Har tenta nu på fredag så kommer att sitta med SQL varje dag nu i flera timmar, känner att jag behöver det
Citera
2011-10-17, 14:22
  #48
Medlem
Amen vf...Nu satt jag o provade mig fram igen. Med JOIN koden.

Kod:
select Namnanstproj.aid from anstalld
Join anstproj on
anstproj
.AID anstalld.AID
GROUP BY Namn
anstproj.aid 
HAVING COUNT
(anstproj.aid) > '2' 

Det som va problemet var att jag va tvungen o lägga till namn till GROUP BY..Jag förstår inte varför, varför kan den inte gruppera med anstproj.aid? Eller varför inte bara med Namn? Det fungerade inte heller. Utan jag måste ha med båda dessa.

Jag antar att det har något o göra med att jag frågar efter Namn, Anstproj.aid i början med select, men jag förstår bara inte varför?
Citera

Stöd Flashback

Flashback finansieras genom donationer från våra medlemmar och besökare. Det är med hjälp av dig vi kan fortsätta erbjuda en fri samhällsdebatt. Tack för ditt stöd!

Stöd Flashback