Avatar billede Slettet bruger
25. maj 2008 - 22:48 Der er 8 kommentarer og
1 løsning

Ny aggregate function

Jeg skal bruge en MS SQL select som i en groupby skal reagere på antallet af linjer.

Ordretabel i forhold til ordrelinjer:

Ordrenr Ordrelinjetekst Ordrelinjebeløb
1      Ifølge spec.            250,00
2      Sokker                1.300,00
3      Oste                    500,00

SELECT O.Ordrenr, xxx(OL.Tekst), SUM(OL.Beløb)
FROM Ordrer AS O LEFT OUTER JOIN
Ordrelinjer AS OL ON OL.OrdreID = O.ID
GROUP BY O.Ordrenr

Spørgsmålet lyder hvordan jeg laver en aggregat funktion, der fungerer på varchar's - og som returner linjens værdi, hvis der er en linje - og "Ifølge spec", hvis der er mere end en.

Og det ville være rigtig lækkert, hvis den stadig returnerer linjens værdi, hvis den er ens for alle berørte linjer.
Avatar billede Syska Mester
26. maj 2008 - 00:08 #1
Ikke 100% med ...

Dvs ... hvis en ordre kun har en Ordrelinjetekst, så skal den kun returnere den ... har den flere, skal den returnere dem alle ?
Avatar billede janus_007 Nybegynder
26. maj 2008 - 01:28 #2
Lyder rimelig weird, har du en datamodel som du kan forklare lidt tydeligere?

Umiddelbart ville jeg bruge mit BL-lag til den slags ;)
Avatar billede Slettet bruger
26. maj 2008 - 08:24 #3
Ok - var lidt sent :)

Det er en grouped left outer join - dvs. at for hver ordre skal jeg have en linje i resultatsættet.

Der er en en-til-mange relation mellem ordre og ordrelinjerne. Dvs. der kan være 0 eller flere linjer per ordre, som skal aggregeres på teksten og beløbet:

Ordre 1 - 2 ordrelinjer:
"sokker", 150
"oste", 100

Skal give 1 linje i resultatsættet:
1, "Ifølge specifikation", 250

Ordre 2 - 1 ordrelinje:
"sokker", 1300

Skal give 1 linje i resultatsættet:
2, "sokker", 1300

Ordre 3 - 0 ordrelinjer:

skal give 1 linje i resultatsættet:
3, null, null

Det jeg leder efter er en funktion a'la Sum() for varchar's. Lige nu bruger jeg enten Max() eller Min() men det giver den uheldige bivirkning at brugerne bliver forvirrede, fordi de tror at det er tilfældigt, hvilken linje der vises :).

Ved 0 ordrelinjer skal den returnere null.
Ved 1 ordrelinje skal den give teksten tilbage.
Ved 2+ ordrelinjer skal den give en fast tekst uafhængigt af hvad der står på de enkelte linjer (her "Ifølge specifikation").

Håber det forklarede det lidt bedre.
Avatar billede Slettet bruger
26. maj 2008 - 08:27 #4
Og problemet med at lægge det i BL-laget er at det giver uhyggeligt mange data-kald og der er stor sandsynlighed for at jeg fucker det op (jeg har ialt 8 hierakiske tabeller som skal joines) og så er der hele performancen...
Avatar billede Syska Mester
26. maj 2008 - 12:49 #5
Hvis du bruger 2005, kan du jo skrive din egen aggregate funktion i .NET.

Her er en som giver en løsning på det:
http://www.experts-exchange.com/Microsoft/Development/MS-SQL-Server/Q_20422619.html
scroll til bunden

// ouT
Avatar billede Slettet bruger
26. maj 2008 - 22:16 #6
Jeg har lige løbet dit link igennem.

Aggregate function må være vejen frem - men kan man lave IF ... ELSE med noget count eller endnu bedre noget SWITCH i sådan en? Jeg forestiller mig at kalde funktionen noget a'la STRSUM() - og så kalde den med mit ordreid - herefter tælle antallet af ordrelinjer. returnere null for 0 linjer, returne teksten for 1 og endelig min faste tekst for 2.

Det jeg spørger om, er noget syntax :).
Avatar billede Syska Mester
27. maj 2008 - 10:43 #7
Så er det jo ikke længere en Aggregate funktion ... hvis den modtager en ting, og returnere en helt anden ... eller jo ... men den bliver vel super slow, hvis du skal lave en DB kald for hver gang STRSUM bliver kaldt ....

Men løser den da ikke dit problem ?
Avatar billede Slettet bruger
27. maj 2008 - 21:31 #8
Jooh - til dels løser den det, men jeg vil lige fumle mig lidt frem med det.

Kast et svar, så jeg kan give point.
Avatar billede Syska Mester
29. maj 2008 - 00:44 #9
helt kalrt ... du siger bare til hvis der er mere ...

// ouT
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester