/ 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
SQL til kontingentskema
Fra : Jørn Andersen


Dato : 11-10-05 22:01

Hej,

Jeg har en database over en forenings medlemmer, hvor jeg gerne vil
have lidt mere styr på kontingentbetalingen.

I den forbindelse vil jeg lave et kontingentskema, hvor man for et år
ad gangen kan se *alle* medlemmernes navne (uanset om de har betalt
endnu) listet lodret og månederne (for et år ad gangen) listet
vandret. I de herfra dannede felter, vil jeg så gerne have betalt
beløb og/eller betalingsdato.

Der er i princippet to tabeller: tblMedlemmer og tblKontingent.
tblKontingent har hver kontingentindbetaling som en post, med bl.a.
flg. felter:
KontingentId (Prim.nøgle)
MedlemId (Fjernnøgle fra tblMedlemmer)
BetaltKr, BetaltDato osv

Hvordan laver jeg nemmest et udtræk, som jeg kan loope mig igennem?
Eller er jeg nødt til at lave to forskellige udtræk - et fra hver
tabel - og så køre de to recordsets i hver sit loop (det ene inden i
den anden)?

Bør man ikke kunne lave en SQL-forespørgsel, som kan trække det ud i
ét recordset?

Nu har jeg grublet over den et stykke tid uden resultat, så gode
forslag er velkomne


Mvh. Jørn

--
Jørn Andersen,
Brønshøj

 
 
Dj Uncas (12-10-2005)
Kommentar
Fra : Dj Uncas


Dato : 12-10-05 08:42

Jørn Andersen wrote:
> Hej,
>
> Jeg har en database over en forenings medlemmer, hvor jeg gerne vil
> have lidt mere styr på kontingentbetalingen.
>
> I den forbindelse vil jeg lave et kontingentskema, hvor man for et år
> ad gangen kan se *alle* medlemmernes navne (uanset om de har betalt
> endnu) listet lodret og månederne (for et år ad gangen) listet
> vandret. I de herfra dannede felter, vil jeg så gerne have betalt
> beløb og/eller betalingsdato.
>
> Der er i princippet to tabeller: tblMedlemmer og tblKontingent.
> tblKontingent har hver kontingentindbetaling som en post, med bl.a.
> flg. felter:
> KontingentId (Prim.nøgle)
> MedlemId (Fjernnøgle fra tblMedlemmer)
> BetaltKr, BetaltDato osv
>
> Hvordan laver jeg nemmest et udtræk, som jeg kan loope mig igennem?
> Eller er jeg nødt til at lave to forskellige udtræk - et fra hver
> tabel - og så køre de to recordsets i hver sit loop (det ene inden i
> den anden)?
>
> Bør man ikke kunne lave en SQL-forespørgsel, som kan trække det ud i
> ét recordset?
>
> Nu har jeg grublet over den et stykke tid uden resultat, så gode
> forslag er velkomne
>
>
> Mvh. Jørn

Du kan godt lave en sql-sætning der finder info i en sætning. Det bliver
noget lignende:

SELECT tblMedlemmer.Id AS MedlemId, tblMedlemmer.Navn AS MedlemNavn,
tblKontingent.KontingentId AS KontId, tblKontingent.MedlemId AS
KontMedlemId WHERE (MedlemId = KontMedlemId)

evt. kan du ogå putte dette på, og finde oplysninger for et enkelt
medlem: AND (MedlemId = '" & strId & "')

Jørn Andersen (13-10-2005)
Kommentar
Fra : Jørn Andersen


Dato : 13-10-05 05:49

On Wed, 12 Oct 2005 09:41:41 +0200, Dj Uncas <mads@blizan.com> wrote:

>Du kan godt lave en sql-sætning der finder info i en sætning. Det bliver
>noget lignende:
>
>SELECT tblMedlemmer.Id AS MedlemId, tblMedlemmer.Navn AS MedlemNavn,
>tblKontingent.KontingentId AS KontId, tblKontingent.MedlemId AS
>KontMedlemId WHERE (MedlemId = KontMedlemId)
>
>evt. kan du ogå putte dette på, og finde oplysninger for et enkelt
>medlem: AND (MedlemId = '" & strId & "')

Jo, det er jeg godt klar over (det er vel blot en alm.
JOIN-forespørgsel).
Den har så den ulempe, at den kun vil udtrække medlemmer, hvor der
faktisk er sket en kontingent-indbetaling. Det kan man så løse med en
LEFT/RIGHT JOIN.

Men problemet opstår, når jeg så vil filtrere på kontingenttabellen.
Hvis jeg fx kun vil udtrække for et bestemt år (fx ... WHERE
Year(tblKontingent.KontingentMaaned) = 2005). Resultatet af dette er,
at jeg så ikke får de medlemmer med i kontingentskemaet, der endnu
ikke har betalt kontingent for i år.

Og selv om man kombinerer det med en IS NULL:
.... WHERE Year(tblKontingent.KontingentMaaned) = 2005 OR
tblKontingent.KontingentMaaned IS NULL
så vil det godt nok medtage de medlemmer i oversigten, der slet ikke
har indbetalt kontingent, men ikke de medlemmer, der fx ikke har
betalt for 2005, men nok for 2004.


Jeg er foreløbig landet på en "workaround", hvor jeg laver to udtræk:
Et af hele medlemslisten og så ét af kontingenterne for det pågældende
år. De bliver så flettet sammen i tre loops indeni hinanden:

' Loop gennem medlemmer
For intMedlCount = 0 To intMaxMedl
' - genererer tabelrækkerne

' Loop gennem månederne
For a = 1 To 12

' Loop gennem kontingentudtrækket
For intKontCount = 0 To intMaxKont
' - finder ud af om der er en "post", der matcher det
' pågældende MedlemsId og den pågældende måned
' Hvis den findes, udskrives den i en tabelcelle
' Hvis ikke udskrives et tomt felt

Selv om de trækkes ud med .GetRows, så er der stadigvæk lidt for meget
loop-arbejde efter min smag - den skal jo faktisk gennem den sidste
loop 12 gange for hvert medlem. Nu er det ikke en megastor forening,
så det går nok, men nævn ikke ordet skalering

Så jeg ville gerne have en lidt mere optimal SQL-forespørgsel, hvis
det kan lade sig gøre.


Mvh. og tak for svar,
Jørn

--
Jørn Andersen,
Brønshøj

Jens Gyldenkærne Cla~ (13-10-2005)
Kommentar
Fra : Jens Gyldenkærne Cla~


Dato : 13-10-05 13:26

Jørn Andersen skrev:

> Så jeg ville gerne have en lidt mere optimal SQL-forespørgsel,
> hvis det kan lade sig gøre.

Hvilken database arbejder du i?

Jeg vil tro at du kan løse problemet ved at lave left join på et
udsnit af kontingent-tabellen (nemlig det der svarer til et bestemt
år):

SELECT *
FROM Medlemmer m LEFT JOIN Kontingent k
   ON    m.medlemID = k.medlemID
   AND    YEAR(k.betaltDato) = 2005
ORDER BY k.betaltDato

Ved at lægge kriteriet som en del af join-betingelsen burde du
slippe for problemet med at skelne mellem folk der har betalt i
andre år end 2005 og folk der aldrig har betalt.
--
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

Jørn Andersen (14-10-2005)
Kommentar
Fra : Jørn Andersen


Dato : 14-10-05 00:27

On Thu, 13 Oct 2005 14:26:24 +0200, Jens Gyldenkærne Clausen
<jens@gyros.invalid> wrote:

>Hvilken database arbejder du i?

Sorry, MS Access 2000

>Jeg vil tro at du kan løse problemet ved at lave left join på et
>udsnit af kontingent-tabellen (nemlig det der svarer til et bestemt
>år):
>
>SELECT *
>FROM Medlemmer m LEFT JOIN Kontingent k
>    ON    m.medlemID = k.medlemID
>    AND    YEAR(k.betaltDato) = 2005
>ORDER BY k.betaltDato

Bortset fra, at Access tilsyneladende ikke understøtter alias'er
(eller hvad nu de m og k hedder) på denne måde, så var det lige det,
der skulle til!

Tusind tak! Så slap jeg for alt for mange loops.

Det åbner jo helt nye døre til at effektivisere nogle af mine gamle
scripts - hvor der i nogle tilfælde er blevet drevet endnu mere
rovdrfit på loops'ene

Det er bare sjovt, at jeg aldrig har set den SQL-variant før. Har du
evt. et link til nogle lidt mere avancerede joins (til Access) end
hvad man ser i de mest simple tutorials?

---
NB: Da jeg skulle afprøve Sql'en direkten i Access gav den dog en
fejlmeddelelse, som jeg troede betød, at den ikke undertsøttede
funktioner (fx YEAR(k.betaltDato)) på dette sted, men senere da jeg
prøvede lykkedes det mig at få den til at æde den.

Det ser ud til, at den kan være lidt ustabil med sine fejlmeddelelser.
Fx tog jeg en Query lavet i én database og kopierede den direkte over
i en anden (strukturelt) ens database, hvor den så gav en
fejlmeddelelse om at den ikke understøttede den pågældende join ...

>Ved at lægge kriteriet som en del af join-betingelsen burde du
>slippe for problemet med at skelne mellem folk der har betalt i
>andre år end 2005 og folk der aldrig har betalt.

Takker endnu en gang!

Mvh. Jørn

--
Jørn Andersen,
Brønshøj

Jens Gyldenkærne Cla~ (14-10-2005)
Kommentar
Fra : Jens Gyldenkærne Cla~


Dato : 14-10-05 10:18

Jørn Andersen skrev:

>> SELECT *
>> FROM Medlemmer m LEFT JOIN Kontingent k
>> ON m.medlemID = k.medlemID
>> AND YEAR(k.betaltDato) = 2005
>> ORDER BY k.betaltDato

> Bortset fra, at Access tilsyneladende ikke understøtter
> alias'er (eller hvad nu de m og k hedder) på denne måde,


Irriterende. Jeg går ud fra at det så virker med AS (as k, as m).


> Det er bare sjovt, at jeg aldrig har set den SQL-variant før.
> Har du evt. et link til nogle lidt mere avancerede joins (til
> Access) end hvad man ser i de mest simple tutorials?

Ikke lige på hånden. Men humlen er at man kan skrive alle former
for kriterier som en del af join-udtrykket - det behøver ikke være
udtryk af formen a.felt = b.felt
--
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

Jørn Andersen (14-10-2005)
Kommentar
Fra : Jørn Andersen


Dato : 14-10-05 15:08

On Fri, 14 Oct 2005 11:18:08 +0200, Jens Gyldenkærne Clausen
<jens@gyros.invalid> wrote:

>> Bortset fra, at Access tilsyneladende ikke understøtter
>> alias'er (eller hvad nu de m og k hedder) på denne måde,
>
>Irriterende. Jeg går ud fra at det så virker med AS (as k, as m).

Ja.

>> Det er bare sjovt, at jeg aldrig har set den SQL-variant før.
>> Har du evt. et link til nogle lidt mere avancerede joins (til
>> Access) end hvad man ser i de mest simple tutorials?
>
>Ikke lige på hånden. Men humlen er at man kan skrive alle former
>for kriterier som en del af join-udtrykket - det behøver ikke være
>udtryk af formen a.felt = b.felt

Jeg har så et opfølgningsspørgsmål:
Der er vel ikke noget, der kommer gratis? Der er vel også forskel på,
hvor mange ressourcer det tager at "køre" forskellige Sql SELECTs -
også selv om de returnerer det samme antal poster?

Jeg prøvede at lave en hurtig omsætning af dit forslag til et
vagtskema, vi har på arbejde. Problematikken er den samme: Alle
medarbejdere skal vises i skemaet, men folk har (heldigvis) ikke
vagt/sygdom/ferie etc. hele tiden.

Men det var meget tydeligt, at når jeg kørte den i Access på min (godt
nok langsomme) bærbare, så tog det faktisk nogle (3-5) sekunder at
levere et svar.

Hvad er mest sandsynligt: Er det en uhensigtsmæssig Sql? Eller skal
jeg kigge på indeksering af tabellerne? Eller noget helt tredje?


Mvh. Jørn

--
Jørn Andersen,
Brønshøj

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

Månedens bedste
Årets bedste
Sidste års bedste