/ Forside / Teknologi / Udvikling / ASP / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
ASP
#NavnPoint
smorch 9259
Harlekin 1866
molokyle 1040
Steffanst.. 758
gandalf 657
smilly 564
gibson 560
cumano 530
MouseKeep.. 480
10  Random 410
Djævelsk boolsk problem i SQL sætning
Fra : Bjarne Damsgaard


Dato : 12-03-03 16:38

Jeg har et problem som jeg nemmest anskueliggør med et eksempel:
Biblioteket har tre tabeller:

Lånere: LånerNavn, LånerID
Bøger: BogNavn, BogID
Udlån: LID, BID

Hvis bib. vil se hvilke bøger jeg har lånt, kan den spørge:

SELECT BogNavn FROM Lånere, Bøger, Udlån WHERE
Lånernavn = 'Bjarne' AND
LånerID = LID AND
BogID = BID;

Hvis den vil vide hvilke bøger Bjarne netop _ikke_ har lånt, hvordan
lyder spørgsmålet da?

mvh Bjarne

 
 
Jens Gyldenkærne Cla~ (12-03-2003)
Kommentar
Fra : Jens Gyldenkærne Cla~


Dato : 12-03-03 17:01

Bjarne Damsgaard skrev:

> Hvis den vil vide hvilke bøger Bjarne netop _ikke_ har lånt,
> hvordan lyder spørgsmålet da?

Svaret afhænger af hvilken database du benytter. I MSSQL kan man
skrive:

SELECT BogID, BogNavn
FROM Bøger
WHERE NOT EXISTS
   (SELECT 't' FROM
    Udlån u INNER JOIN Lånere l
   ON u.LID = l.LånerID
   WHERE l.Lånernavn = 'Bjarne'
   AND u.BID = Bøger.BogID)

Hvis EXISTS ikke er understøttet, men subselects er (fx i Access)
kan man skrive:

SELECT BogID, BogNavn
FROM Bøger
WHERE BogID NOT IN
   (SELECT u.BID FROM
    Udlån u INNER JOIN Lånere l
   ON u.LID = l.LånerID
   WHERE l.Lånernavn = 'Bjarne')

Hvis subselects heller ikke er understøttet (fx i mysql 3.x) har
jeg ikke noget umiddelbart bud på en løsning.
--
Jens Gyldenkærne Clausen
Svar venligst under det du citerer, og citer kun det der er
nødvendigt for at forstå dit svar i sammenhængen. Se hvorfor og
hvordan på http://usenet.dk/netikette/citatteknik.html

Bjarne Damsgaard (12-03-2003)
Kommentar
Fra : Bjarne Damsgaard


Dato : 12-03-03 17:42

On Wed, 12 Mar 2003 17:00:45 +0100, Jens Gyldenkærne Clausen
<jens@gyros.invalid> wrote:

>Svaret afhænger af hvilken database du benytter. I MSSQL kan man
>skrive:
>
>SELECT BogID, BogNavn
>FROM Bøger
>WHERE NOT EXISTS
>    (SELECT 't' FROM
>     Udlån u INNER JOIN Lånere l
>    ON u.LID = l.LånerID
>    WHERE l.Lånernavn = 'Bjarne'
>    AND u.BID = Bøger.BogID)
>
Mange tak for det præcise svar!

Jeg har hjemmesiden hos Brinkster (Access2000). Jeg har i mellemtiden,
ved at falde over det rigtige afsnit i en bog(!), af Lars Ingesman,
fundet frem til til følgende sætning:

SELECT BogID, BogNavn
FROM Bøger
WHERE NOT EXISTS
(SELECT * FROM Lånere, Udlån
WHERE LånerNavn = 'Bjarne'
AND LID = LånerID
AND BID = BogID)

der også ser ud til at virke. Er INNER JOIN sætningen mere effektiv
end min newbie-løsning?


Jens Gyldenkærne Cla~ (13-03-2003)
Kommentar
Fra : Jens Gyldenkærne Cla~


Dato : 13-03-03 10:31

Bjarne Damsgaard skrev:

> SELECT BogID, BogNavn
> FROM Bøger
> WHERE NOT EXISTS
> (SELECT * FROM Lånere, Udlån
> WHERE LånerNavn = 'Bjarne'
> AND LID = LånerID
> AND BID = BogID)
>
> der også ser ud til at virke. Er INNER JOIN sætningen mere
> effektiv end min newbie-løsning?

Så vidt jeg husker er der ikke i praksis forskel på at lave et join
eksplicit:
   SELECT <felter>
   FROM foo INNER JOIN bar
   ON foo.barID = bar.barID

- og det samme join implicit:

   SELECT <felter>
   FROM foo, bar
   WHERE foo.barID = bar.barID

Jeg foretrækker afgjort at skrive et eksplicit join, fordi det i
mine øjne er lettere at se hvordan de enkelte tabeller kædes
sammen. Hvis man har kriterier der ikke hører til sammenkædningen
(i ovenstående fx bar.Navn = 'Baz') vil de med et implicit join
være blandet sammen med join-kriterierne, mens det med et eksplicit
join er tydeligt hvilke kriterier der vedrører sammenkædningen af
tabeller og hvilke der ikke gør.

Noget der til gengæld nok har en negativ betydning mht.
effektivitet i dit eksempel er at du bruger "SELECT *". En EXISTS-
forespørgsels eneste formål er at være enten tom eller ikke-tom.
Ved at inkludere alle felter beder du databasen om at hente en
masse data der ikke er brug for. Skriv fx "SELECT True", "SELECT 1"
eller SELECT 'x' i stedet for (NB: True/False findes ikke i MSSQL,
derfor var mit eksempel SELECT 't').
--
Jens Gyldenkærne Clausen
Svar venligst under det du citerer, og citer kun det der er
nødvendigt for at forstå dit svar i sammenhængen. Se hvorfor og
hvordan på http://usenet.dk/netikette/citatteknik.html

Søg
Reklame
Statistik
Spørgsmål : 177551
Tips : 31968
Nyheder : 719565
Indlæg : 6408836
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste