Med OS2ai forsøger Aarhus Kommune og OS2-fællesskabet at give offentlige medarbejdere adgang til generativ AI uden at gøre kommunerne mere afhængige af amerikanske techgiganter.
Jeg er en anelse uenig med nielle (for en gang skyld :)) - jeg ville da gøre som du lægger op til, da jeg er at den holdning at hvis databasen kan få lov til at lave alt arbejdet i et kald, så er det i de fleste tilfælde hurtigere end at skulle omkring fortolket script-kode og kalde databasen i to omgange. Derfor til jeg tro at flg. ville løse din udfordring:
SELECT SUM([beløb]) * (SELECT valuta FROM tabel2 WHERE iso='DKK') AS [valutabeløb] FROM ordre
...eller hvad dine tabeller og kolonner nu hedder :)
Ja, hvis der rent faktisk er en relation mellem de to tabeller, så kunne en join også være en mulighed, men du skal så nok overveje din WHERE-clause, ellers ville du vel ende med flere summer (en pr. valutakode)...
Så vidt jeg har forstået opgaven så drejer det sig om at vi har en ordre i den ene tabel, og nogle vekselkurser i den anden tabel. Det er så meningen at ordren tælles sammen som en total, og at denne derefter præsenteres i beløb svarende til de forskellige mulige valuta.
Hvis dette er korrekt, er der altså ikke nogen direkte forbindelse med posterne i den ene og posterne i den anden tabel. Derfor lægger løsningen heller ikke op til en join (INNER eller andet) i dette tilfælde.
Hvad angår udtrykket:
SELECT SUM([beløb]) * (SELECT valuta FROM tabel2 WHERE iso='DKK') AS [valutabeløb] FROM ordre
- så går min betænkelighed her på om hvorvidt sub-select'en:
(SELECT valuta FROM tabel2 WHERE iso='DKK')
- men denne løsning bliver udført en gang for hver række i tabellen ”ordre” eller om den bliver udført én gang i alt og værdien så bliver genbrugt for hver række i ”ordre”. Jeg tør ikke gætte på om det er det ene eller det andet som gælder (jeg er for resten ikke en gang helt sikker på om det overhovedet kan køre).
Mht. ideen om hvor at beregningerne skal gennemføres, så vil jeg bare påpege at det vist afhænger af så mange forskellige faktorer til at man kan sige noget generelt. Normalt er en database ikke specielt optimeret til at lave beregninger, men mere på at hive data ud, og man kan sagtens forestille sig at ASP-scriptet ville bruge færre ressourcer end SQL-databasen på en given opgave.
Jeg har testet denne (eller i det mindste en nær ved magen til)
SELECT SUM([beløb]) * (SELECT valuta FROM tabel2 WHERE iso='DKK') AS [valutabeløb] FROM ordre
i en Access 2000 db med querybuilder og den kører skam godt nok. Hvad angår databasens evne til at regne, så tror jeg ikke det er der den bruger flest resurser, det er (iflg. min overbevisning) klart at få linet data op så de er klar til at arbejde med (herunder regne).
Hvis jeg kort skulle skitsere hvordan jeg tror database-motoren vil håndtere denne forspørgsel, så ville det være noget med at
1. finde alle beløb mens de akkumuleres 2. finde den valuta som har iso DKK 3. gange summen fra pkt. 1 med værdien af feltet fra pkt. 2
og returnere et recordset som indeholder dette resultat...
Okay, vi er så åbenbart lidt uenige om hvad opgaven består i. :-)
Mit udgangspunkt er, at vi har en ordre, hvor der er tilknyttet en valutakode (kunden befinder sig i et bestemt land). Det er så opgaven at opsummere linieværdierne (som er i DKK) og så omregne dette til et beløb i modtagerens valuta. Mest realistisk situation ville jo nok være, hvis der var en tabel med et ordrehoved, en med ordrelinierne og en med valutakurserne:
SELECT SUM(T1.beløb) * T2.kurs AS værdi FROM Ordrehoved H INNER JOIN Ordrelinier L ON H.ordrenr = L.ordrenr INNER JOIN Valutaer V ON V.ValutaKode = H.ValutaKode WHERE H.ordrenr = 225
Men hvis det var som du formoder, at værdien skal angives i forskellige valutaer, ville det stadig være mest indlysende med en inner join (sort of), dog uden sammenknyttende værdi og med en temp tabel:
SELECT V.ValutaKode, O.Tbeløb * V.ValutaKurs AS værdi FROM (SELECT SUM(beløb) AS Tbeløb FROM Ordrelinier WHERE ordrenr = 225 ) O, Valutaer V
Og igen var jeg for hurtig (okay, så for sløset da!) :-(
SELECT SUM(L.beløb) * V.kurs AS værdi FROM Ordrehoved H INNER JOIN Ordrelinier L ON H.ordrenr = L.ordrenr INNER JOIN Valutaer V ON V.ValutaKode = H.ValutaKode WHERE H.ordrenr = 225
Undskyld - men jeg jeg sidder og afprøver alle jeres svar (tak for dem) men har ikke fundet løsningen endnu. Det er lidt kringlet: Jeg har en tabel hvor der står beløb i et felt (beloeb), i et andet felt i samme tabel er der angivet hvilken valuta beløbet er angivet i (valuta). Så har jeg en anden tabel med valutakurser(Exchange_rate) i den er der et felt for hver valuta (from) og en kurs (exchange). Nu skal jeg så have lagt nogle beløb sammen og have det ud i den rigtige kurs.
SELECT DISTINCT A.BUKRS as kode, COUNT(A.EQUNR) AS antal, B.DESCRIPTION as navn, SUM(A.ANSWT) * C.ECXHANGE AS vaerdi FROM dbo.EQUIPMENT AS A INNER JOIN dbo.COMPANY_CODE AS B ON A.BUKRS = B.BUKRS INNER JOIN dbo.EXCHANGE_RATE AS C ON A.WAERS = C.[FROM] WHERE (A.STATUS NOT LIKE '*DLFL*' AND A.STATUS NOT LIKE '*INAK*') GROUP BY A.BUKRS,B.DESCRIPTION,C.ECXHANGE ORDER BY A.BUKRS
Ville det ikke være mere logisk udelade DISTINCT og skrive sådan:
SELECT A.BUKRS as kode, COUNT(A.EQUNR) AS antal, B.DESCRIPTION as navn, SUM(A.ANSWT * C.ECXHANGE) AS vaerdi FROM dbo.EQUIPMENT AS A INNER JOIN dbo.COMPANY_CODE AS B ON A.BUKRS = B.BUKRS INNER JOIN dbo.EXCHANGE_RATE AS C ON A.WAERS = C.[FROM] WHERE (A.STATUS NOT LIKE '*DLFL*' AND A.STATUS NOT LIKE '*INAK*') GROUP BY A.BUKRS,B.DESCRIPTION,C.ECXHANGE ORDER BY A.BUKRS
Eller hvis det ikke virker (ved ikke rigtigt om man bør foretage en multiplikation inden i en SUM:
SELECT A.BUKRS as kode, COUNT(A.EQUNR) AS antal, B.DESCRIPTION as navn, SUM(A.ANSWT) * AVG(C.ECXHANGE) AS vaerdi FROM dbo.EQUIPMENT AS A INNER JOIN dbo.COMPANY_CODE AS B ON A.BUKRS = B.BUKRS INNER JOIN dbo.EXCHANGE_RATE AS C ON A.WAERS = C.[FROM] WHERE (A.STATUS NOT LIKE '*DLFL*' AND A.STATUS NOT LIKE '*INAK*') GROUP BY A.BUKRS,B.DESCRIPTION,C.ECXHANGE ORDER BY A.BUKRS
Oops, jeg er virkelig for hurtig på tasterne. Da EXCHANGE feltet er en del af GROUP BY, kan det naturligvis ikke være en del af en aggregat funktion. Burde altså være:
SELECT A.BUKRS as kode, COUNT(A.EQUNR) AS antal, B.DESCRIPTION as navn, SUM(A.ANSWT) * C.ECXHANGE AS vaerdi FROM dbo.EQUIPMENT AS A INNER JOIN dbo.COMPANY_CODE AS B ON A.BUKRS = B.BUKRS INNER JOIN dbo.EXCHANGE_RATE AS C ON A.WAERS = C.[FROM] WHERE (A.STATUS NOT LIKE '*DLFL*' AND A.STATUS NOT LIKE '*INAK*') GROUP BY A.BUKRS,B.DESCRIPTION,C.ECXHANGE ORDER BY A.BUKRS
Prøv lige at se bort fra firmanavnet i første omgang (mindre kompleksitet = bedre overskuelighed :)):
SELECT DISTINCT A.BUKRS as kode, COUNT(A.EQUNR) AS antal, SUM(A.ANSWT) * C.ECXHANGE AS vaerdi FROM dbo.EQUIPMENT AS A INNER JOIN dbo.EXCHANGE_RATE AS C ON A.WAERS = C.[FROM] WHERE (A.STATUS NOT LIKE '*DLFL*' AND A.STATUS NOT LIKE '*INAK*') GROUP BY A.BUKRS,C.ECXHANGE ORDER BY A.BUKRS
Hvad giver det?
Og er der i øvrigt ikke redundans i fremmednøglerne...? Hvis jeg forstår dit database-design korrekt, så er der en reference fra hver af EQUIPMENT-rækkerne over i EXCHANGE og er de så alle ens for de grupperinger du laver. Hvis ikke, så kan det jo godt give nogle sære resultater (hvis man blander pund sterling og burmesiske ringit)...
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.