Avatar billede ravelab Praktikant
26. september 2012 - 09:59 Der er 8 kommentarer og
1 løsning

Fjerne dubletter i tabel

Har lavet den samme SQL på 2 forskellige måder, som begge to giver mig dubletter og de samme antal rows, hvor jeg gerne vil fjerne de dubletter med den laveste date_diff.

Den første metode bliver lavet med 2 SELECTS med en UNION i mitten, som samler data sammen i en tabel. Her er date_diff, COUNT, Amount aliases (Beregning AS alias) og aliases kan efter min viden om GROUP BY ikke indgå i sådan statment til sorter data den vej igennem.

SELECT
  FROM
    WHERE
GROUP BY

UNION

SELECT
  FROM
    WHERE
GROUP BY

ORDER BY account

Den anden metode gør brug af følgende SQL tilgang. Her er account, date_diff, COUNT, Amount aliases

SELECT
  FROM
    WHERE
GROUP BY

Har prøvet at løse mit problem ved at gøre følgende, men dette virker ikke. Måske kan nogen fikse det eller se min fejl.

SELECT * FROM (

SELECT
  FROM
    WHERE
GROUP BY

UNION

SELECT
  FROM
    WHERE
GROUP BY

ORDER BY account

) GROUP BY account, MAX(date_diff)

Men igen er aliases det der sætter sætter en stopper for mit forsøg på at rettet op på problemet.

Har lavet nogle demo data i Excel, så det bliver nemmer at se hvad jeg får nu og hvor det er jeg gerne vil hen efter problemet er blevet fikset.

Link til test data screenshot:
http://i47.tinypic.com/24dmxw3.jpg

Link til dem vil se det i fuld størrelse:
http://i47.tinypic.com/24dmxw3.jpg
26. september 2012 - 10:54 #1
Det ville være ulige nemmere at forholde sig til, hvis du viste den eller de tabeller du selecter fra og måske også skriver de selects du har prøvet fuldt ud snarere end bare i skeletform.
Avatar billede ravelab Praktikant
26. september 2012 - 11:12 #2
De tabeller der tages data fra vil være alt for store og komplekse til at du lige sådan uden videre ville kunne forstå deres opbygning. Så dette ville ikke give nogen værdig for dig eller mig. Har prøvet at gøre dette spørgsmål så simpelt og præcist som overhoved muligt.

Men kan dog gøre det lidt nemmer ved at sige at date_diff og account er det, som er vigtigt i denne her sammenhæng. date_diff er en beregning ud fra en start dato og en slut dato, som så får en alias bagefter.
26. september 2012 - 12:06 #3
Det vil du ikke være med til?  Jamen det bestemmer du.  Så håber jeg du får hjælp fra anden side.  (Jeg undrer mig forøvrigt på, hvordan man kan konstruere mssql tabeller sådan at man ikke kan forstå opbygningen.)
Avatar billede ravelab Praktikant
26. september 2012 - 12:21 #4
Er det selve koden du vil se eller selve tabellerne? Tror nemlig vi snakker forbi hinanden her. Jeg opfattede det som om du ville se tabellens opbygning og ikke koden.
26. september 2012 - 13:16 #5
Der er egenligt ikke noget jeg vil se.  Det er dig der spørger om hjælp.  Hvis det er mig der skal hjælpe, så vil det være nødvendigt, at du kommer med flere oplysninger.  Hvis du mener, at du har strukturet spørgsmålet optimalt og helst ikke vil gøre mere, så er det fra min side i orden.

Jeg noterer mig, at du vil selecte fra en tabel, eller måske fra to tabeller i hver sin del af unionen.  Jeg er interesseret i tabellens/tabellernes opbygning, tabellens felter.  (Jeg kan ikke selv forestille mig, at det skulle være svæt at forstå, men det ved du nok bedre end mig.)  Hvis det er en tabel med et stort antal felter, så de felter der har betydning for selecten.  Det vil også være godt at se den eller de selects du har skrevet og som har ledt til det uønskede resultat.

Men jeg vil helst ikke spilde mere af din tid med at diskutere dette videre.  Hvis du vil vise mig det, så er det fint.  Ellers foreslår jeg, at vi stopper her.
Avatar billede ravelab Praktikant
26. september 2012 - 13:33 #6
Tror det bliver nemmest at tage udgangspunkt i løsning 1. De tabeller jeg laver SELECT på før og efter UNION er en og de samme, men hvor der i den ene SELECT er fokus på xi_account1 og i den anden fokus på xi_account2. Så grunden til at lavede UNION løsning var bare for at samle account 1 og 2 i samme felt, frem for at lade dem stå på samme række.

Men her løsning 1:

SELECT
      CASE
      WHEN [xi_account1] IS NULL THEN [xi_account2]
      ELSE [xi_account1]
      END AS 'Account'
      ,DATEDIFF(DAY, MIN(isnull([xi_date], DATEADD(DAY,((DAY(DATEADD(month, 1, GETDATE())))-1)*-1 ,DATEADD(month, 1, GETDATE())))), GETDATE()) AS 'date_diff'
      ,SUM(([xv_total] + [xv_old_total]) - ([xv_paid] + [xv_old_paid])) AS 'Amount'

FROM [xi]

INNER JOIN [xv] ON [xv_seq] = [xi_seq]

WHERE ([xi_status] = 3) AND (([xv_total] + [xv_old_total]) - ([xv_paid] + [xv_old_paid]) > 101)

GROUP BY [xi_account1], [xi_account2]

ORDER BY 'Account'
26. september 2012 - 13:42 #7
Du forespørger åbenbart i to tabeller som du kalder xi og xv, men jeg konstaterer, at du ikke vil vise dem.  Jeg står af.  Ha' en fortsat god dag.
Avatar billede Slettet bruger
26. september 2012 - 22:12 #8
Dubletter med den laveste date_diff:

select *
from
(
SELECT Account, Count, date_diff, Amount
,row_number() over(partition by Account ordre by date_diff desc) Nr
from Tabel
) s1
where Nr > 1
Avatar billede ravelab Praktikant
27. september 2012 - 10:06 #9
#8 Super det var løsningen. Meget nemt at gøre brug af. Var mine forklaring svære at havde med at køre som Christian_Belgien udtalte? P.S du får lige dine points her.
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

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