07. august 2007 - 14:44Der er
3 kommentarer og 1 løsning
Struktur problem?
Hej Eksperten
Jeg skal til at opbygge en database, men jeg har et lille problem som jeg ikke kan finde løsningen på. Forretningslogikken er lidt svær at forklare, men jeg forsøger.
Jeg har et lager hvor det er muligt at tilføje/fjerne produkter. Hvis der ikke er sket nogle ændringer skal beholdningen overføres til næste dag. Den 6/8 er der 10 stk. på lager, der sker ingen bevægelser d. 7/8 og 8/8, men den 9/8 fjernes der 2 stk., altså:
Normalt vil jeg sige, at man i en database ikke skal gemme ens records, dvs recorden d. 6-8/8 er ens bortset fra datoen. Du skal i stedet for kun gemme de datoer hvorpå der sker transkaktioner (tilgang/afgang fra lager). F.eks. vil du i dit tilfælde kun have følgende records i databasen:
6/8 10 stk 9/8 8 stk
Når du så skal finde beholdningen på en bestemt dato, kan du evt. benytte følgende sql: select top 1 <beholdningsfelt> from <tabel> where <datofelt> <= #din_dato
Mit problem er at jeg skal udregne leje på baggrund af den daglige beholdning.
sådan her: 6/8-2007 10 stk. gange 1 = 10 kr. 7/8-2007 10 stk. gange 1 = 10 kr. 8/8-2007 10 stk. gange 1 = 10 kr. 9/8-2007 8 stk. gange 1 = 8 kr. 10/8-2007 8 stk. gange 1 = 8 kr.
Personligt ville jeg nok oprette en beholdningstabel og en transaktionstabel. Beholdningstabellen kunne enten indeholde den til enhver tid gældende lagerbeholdning eller en beholdning fra seneste status. For at få lagerbeholdningen på et givet tidspunkt ville man så skulle regne enten "forlæns" eller "baglæns". Der er fordele og ulemper ved begge metoder.
Hvis man tager udgangspunkt i en fast statusbeholdning skal den aktuelle beholdning altid udregnes hver gang den bruges. Til gengæld skal kun transaktionstabellen opdateres løbende.
Hvis man tager udgangspunkt i den til enhver tid gældende lagerbeholdning, skal både lagerbeholdnings- og transaktionstabellen opdateres hver gang der sker ændringer i lagerbeholdningen. Til gengæld er den aktuelle lagerbeholdning altid tilgængelig uden at skulle udregnes.
For begge gælder, at ALLE ændringer i lagerbeholdning skal udløse en transaktionsrecord i transaktionstabellen. Hver gang der plukkes fra lageret, hver gang der modtages og sættes varer på plads, hver gang der konstateres et svind (eller der findes en fejlplaceret vare og denne lægges på lager) skal der oprettes en transaktion. Det er den eneste måde man kan være sikker på, at kunne regne sig frem til den korrekte lagerbeholdning på et givet tidspunkt.
For versionen med en "statusbeholdning" vil en mulig tabel-konstruktion derfor kunne være:
Varebeskrivelse: Id Varenummer Varebeskrivelse Indkøbspris Salgspris Leverandør Varetype
Statusbeholdning: Id VareId Tidspunkt Lagerbeholdning
Transaktioner: Id StatusId Tidspunkt Type Lagerbevægelse
Den aktuelle lagerbeholdning kunne findes og vises ved at udføre noget lign. denne forespørgsel:
SELECT v.Varenummer, v.Varebeskrivelse, v.Salgspris, NZ(s.Lagerbeholdning, 0) + NZ(SUM(tr.Lagerbevægelse), 0) AS Lager FROM Varebeskrivelse v LEFT JOIN Statusbeholdning s ON s.VareId = v.Id LEFT JOIN Transaktioner tr ON tr.StatusId = s.Id WHERE v.Varenummer = 238 GROUP BY v.Varenummer, v.Varebeskrivelse, v.Salgspris
Den ønskede statistik (grundlag for regning) ville så kunne laves ca. sådan:
SELECT v.Varenummer, v.Varebeskrivelse, d.Dato, NZ(s.Lagerbeholdning, 0) + NZ(SUM(tr.Lagerbevægelse), 0) AS Lager, v.LejePrDag, NZ(s.Lagerbeholdning, 0) + NZ(SUM(tr.Lagerbevægelse), 0) * LejePrDag AS Dagsleje FROM Varebeskrivelse v, Datoer d LEFT JOIN Statusbeholdning s ON s.VareId = v.Id LEFT JOIN Transaktioner tr ON tr.StatusId = s.Id WHERE v.Varenummer = 238 AND d.Dato BETWEEN #01/01/07# AND #01/31/07# AND tr.Tidspunkt < (SELECT MAX(Tidspunkt) FROM Transaktioner WHERE StatusId = s.Id AND Date(Tidspunkt) <= d.Dato) GROUP BY v.Varenummer, v.Varebeskrivelse, d.Dato, v.LejePrDag
Bemærk, at vi her tilføjer en ekstra tabel, nemlig Datoer. Det er en såkaldt støttetabel, som bruges som omdrejningspunkt for statistikken. Den indeholder simpelthen alle datoer inden for den årrække, som programmet forventes at bruges:
Datoer: Dato
(jeg har dog ikke på nogen måde testet ovenstående, så reelt er det ren teori, men du kan jo prøve det af... :-)
Synes godt om
Slettet bruger
08. august 2007 - 08:49#4
nordclc> husk DESC på dato eller brug LAST i stedet for!~)
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.