Hej,
Jag försöker få ut alla författare som är födda före 1950 i min SQL-sats. Det är något som inte fungerar. I Access får jag felmeddelandet; "Typblandningfel i villkorsuttryck", vilket i praktiken innebär att jag skulle jämför äpplen med päron. fodelse_datum är av sorten datum/tid så jag förstår inte vad problemet är.
SELECT fornamn&" "&efternamn AS namn
FROM (SELECT * FROM tblForfattare WHERE fodelse_datum <= '1950-01-01');
Lite hjälp vore fint :e
@ndersMedlem sedan juni 200032 969 inlägg Prova med # runt datumet istället för apostrofer.
Mvh
LarsGMedlem sedan dec. 200012 464 inlägg Varför har du en härledd tabell?
SELECT fornamn & ' ' & efternamn AS namn
FROM tblForfattare
WHERE fodelse_datum <= #1950-01-01#
Anledning till det är att det kommer en fortsättning på sql-satsen. Kom inte vidare i och med föregående fel. Här är hela satsen.
SELECT forfattar_id, fornamn&" "&efternamn AS namn
FROM (SELECT * FROM tblForfattare WHERE fodelse_datum < '1950-01-01') WHERE tblBOK.kategoriID = 3;
@ndersMedlem sedan juni 200032 969 inlägg Den frågan kan inte ge rätt resultat. Skriv en join istället.
SELECT forfattar_id, fornamn &" "& efternamn AS namn
FROM tblForfattare INNER JOIN tblBOK on tblBOK.forfattar_id = tblForfattare.id WHERE tblForfattare.fodelse_datum < #1950-01-01#) AND tblBOK.kategoriID = 3
Du kanske får rätta till fältnamn i frågan.
mvh
Så här ser min slutliga fungerande lösning ut. Jag vet att den förmodligen går att designa på ett snyggare sätt men detta var det jag lyckades åstadkomma med mina nuvarande SQL-kunskaper :)
SELECT fornamn&" "&efternamn AS namn FROM tblForfattare WHERE forfattar_id = ANY(SELECT forfattar_id FROM tblBok_skriven_av b1
WHERE b1.isbn_nr = ANY(SELECT b2.isbn_nr FROM tblbok AS b2 WHERE b2.kategoriID=3) AND fodelse_datum < #1950-01-01#);
Med utgångspunkt från min lösning ovan så vore jag tacksam om någon kunde göra om denna SQL-sats så att man använder sig av JOIN istället om det nu är att föredra istället för en massa nästlande och resurskrävande SELECT-satser. Behöver ett bra exempel på det :)
Anders, i och med att jag inte har något författarattribut lagrat i BOK-relationen fungerar det väl inte att göra en jämförelse som du gör i din JOIN-sats avseende tblforfattare.författar_id = tblforfattar.id? En bok i mitt system kan vara skriven av 1..* författare varför jag har en relation som heter Bok_skriven_av (lagring sker av isbnnummer och författar_id) som medger lagring av flera författare per bok.
Jag skulle nog ha angett huvudfrågan i klartext förut. Jag vill få ut samtliga författare födda före 1950 och som skriver poesi.
Mitt tankesätt var då att först extrahera samtliga böcker som tillhör poesikategorin (3) i tblBok. Därefter matchar jag samtliga erhållna isbn-nummer från tblBok med isbn-numrena i Bok_skriven_av samt villkoret ålder < 1950. Har jag tänkt helt fel? :)
@ndersMedlem sedan juni 200032 969 inlägg Då förstår jag hur det hänger ihop. :)
Jag hade då skrivit en dubbel join. Dvs joina bok-tabellen -> bok_skriven_av-tabellen -> författartabellen, och sätt de villkoren du vill ha i where.
Mvh
LarsGMedlem sedan dec. 200012 464 inlägg Det är inte så bra i detta fall. T.ex. om någon skriva flera poesiböcker så får du flera förekomster av den författaren.
SELECT fornamn & ' ' & efternamn AS namn
FROM tblForfattare
WHERE forfattar_id in
(SELECT forfattar_id
FROM tblBok_skriven_av b1 inner join tblbook b2 on b1.isbn_nr = b2.isbn_nr
WHERE fodelse_datum < #1950-01-01#
and kategori = 3)
I detta fall är det bättre med en subselect.
Jag läser en databaskurs på högskolan just nu och visst har vi gått igenom JOIN men jag har väl dragit mig för att använda dem än så länge :)
Din teori låter dock väldigt smakfull och enkel! Jag ska försöka skriva om SQL-satsen och sedan återkomma med en ny lösning!
/F
Då kan man väl använda sig av DISTINCT?
LarsGMedlem sedan dec. 200012 464 inlägg Att använda distinct medför ofta sämre prestanda och sedan kan man inte säga att
select distinct a.* from a join b on a.pk = b.pk
är samma sak som som
select * from a where pk in (select pk from b)
@ndersMedlem sedan juni 200032 969 inlägg
LarsG skrev:
Det är inte så bra i detta fall. T.ex. om någon skriva flera poesiböcker så får du flera förekomster av den författaren.
....
I detta fall är det bättre med en subselect.
Japp, jag tänkte inte så långt. :)
Mvh
Vad är det som inte är bra med min sql-fråga jag skrev förut förutom att den har nästlande SELECT-satser?
SELECT fornamn&" "&efternamn AS namn FROM tblForfattare WHERE forfattar_id = ANY(SELECT forfattar_id FROM tblBok_skriven_av b1
WHERE b1.isbn_nr = ANY(SELECT b2.isbn_nr FROM tblbok AS b2 WHERE b2.kategoriID=3) AND fodelse_datum < #1950-01-01#);
Den fungerar i Access...
LarsGMedlem sedan dec. 200012 464 inlägg Det är inget fel med din fråga. Det går att skriva frågor som ger samma resultat på många olika sätt.
Jo, det e sant, men de kan väl vara mer eller mindre resurskrävande?
LarsGMedlem sedan dec. 200012 464 inlägg Jo. Principiellt så skulle en databashanterare skapa samma exekveringsplan oavsett hur frågan är skriven men i praktiken kan det bli stora skillnader. Det kan också skilja sig mellan olika DBMS. En typ av frågor kan optimeras väldigt bra i en DBMS medan andra inte alls klarar av den typen av frågor utan att t.ex. göra kostsamma mellanlagringar. Det är därför väldigt vanskligt att uttala sig generellt om att en viss typ av frågor är sämre än andra ur prestandasynpunkt.
Detta var bara vad jag hört andra säga tidigare, främst angående nästlande SELECT-satser :)