Avatar billede vraa Nybegynder
15. marts 2006 - 08:24 Der er 37 kommentarer og
1 løsning

Fjern øverste række i select ved duplikationer

Jeg skal udforme en select statement som ikke tager øverste række med ved duplikationer.
F.eks ved følgende tabel:

ID    Navn
1      Navn1
2      Navn1
3      Navn2
4      Navn2
5      Navn2
6      Navn3
7      Navn3

Her vil jeg gerne udtrække rækkerne med ID: 2,4,5,7. Dvs. rækkerne med ID 1,3,6 ikke skal med da de er den øverste række ved duplikationer.

Har jeg forklaret mig nogenlunde forståeligt?
Avatar billede jensen363 Forsker
15. marts 2006 - 08:26 #1
Du kan vælge at gruppere på Navn i en forespørgsel ( undlad ID )
Avatar billede vraa Nybegynder
15. marts 2006 - 08:31 #2
Hvordan får jeg så kun de rækker jeg skal bruge? Har du et eksempel?
Avatar billede terry Ekspert
15. marts 2006 - 08:36 #3
SELECT DISTINCT Navn From yourTable
Avatar billede vraa Nybegynder
15. marts 2006 - 08:37 #4
terry-> Så får jeg kun række med ID: 1,3,6. Jeg skal bruge 2,4,5,7
Avatar billede terry Ekspert
15. marts 2006 - 08:39 #5
SELECT DISTINCT Navn From yourTable doesnt give you an ID

Why do you need the ID?
Avatar billede vraa Nybegynder
15. marts 2006 - 08:41 #6
Jeg vil gerne lige tilføje to rækker i min eks. takbel:

ID    Navn
1      Navn1
2      Navn1
3      Navn2
4      Navn2
5      Navn2
6      Navn3
7      Navn3
8      Navn4
9      Navn5

Så skal mit udtræk være med ID: 2,4,5,7 og 8,9

Jeg skal kun undvære den øverste række ved duplikationer.
Avatar billede terry Ekspert
15. marts 2006 - 08:44 #7
That needs quite a complicated selected
Avatar billede eagleeye Praktikant
15. marts 2006 - 08:45 #8
Du vil altid havde den højste ID for et navn?
Eks som jensen363 mener:

SELECT navn, Max(id) AS Maxid FROM Navn GROUP BY navn
Avatar billede jensen363 Forsker
15. marts 2006 - 08:46 #9
Er det præcis ID 2,4,5,7,8,9 du vil udtrække ?
Avatar billede terry Ekspert
15. marts 2006 - 08:48 #10
Where ther is only 1 record with same name then include in select
where the is more than one record with same name then dont include the on ewith lowest ID
Avatar billede eagleeye Praktikant
15. marts 2006 - 08:59 #11
Ja så dur den ikke, jeg så forkert :)

Men så kan du gøres sådan her:

SELECT id, navn FROM navn WHERE id not in (SELECT min(n.id) AS Minid FROM navn n GROUP BY n.navn HAVING count(n.id) > 1;
Avatar billede vraa Nybegynder
15. marts 2006 - 09:00 #12
Sorry men den er lidt tricky og forklare.

- Rækkerne med ID 1 og 2 har samme navn. Derfor skal jeg kun udtrække rækken med ID 2.
- Rækkerne med ID 3,4 og 5 har samme navn og der skal jeg kun udtrække rækkerne 4 og 5.
- Rækken med ID 8 har et navn der kun forekommer én gang så den skal også med. Det samme med rækken med ID 9.

Dvs. at når der er duplikationer i Navn-kolonnen skal alle duplikationer med undtagen den første forekomst.
Rækker hvor der ikke er duplikationer i Navn-kolonnen, skal også med i udtrækket.

Jeg hæver lige indsatsen til 60 point :-)
Avatar billede eagleeye Praktikant
15. marts 2006 - 09:01 #13
der mangler en slut ) imellem 1 og ;

SELECT navn, id FROM navn WHERE id not in (SELECT min(n.id) AS Minid
FROM navn n GROUP BY n.navn HAVING count(n.id) > 1);
Avatar billede jensen363 Forsker
15. marts 2006 - 09:06 #14
Du kan lave den via to forespørgsler :

Den første identificerer dubletterne :

SELECT Min(Tabel.ID) AS MinOfID, Count(Tabel.Navn) AS AntalOfNavn, Tabel.Navn
FROM Tabel
GROUP BY Tabel.Navn
HAVING (((Count(Tabel.Navn))>1));
Avatar billede jensen363 Forsker
15. marts 2006 - 09:09 #15
Den anden forespørgsel ser således ud :

SELECT Tabel.ID, Tabel.Navn
FROM Tabel LEFT JOIN qryFindDelmængde ON Tabel.ID = qryFindDelmængde.MinOfID
WHERE (((qryFindDelmængde.MinOfID) Is Null));
Avatar billede terry Ekspert
15. marts 2006 - 09:12 #16
as far as I can see, eagleeye's does it in a single SQL, which is what I would have done.
Avatar billede jensen363 Forsker
15. marts 2006 - 09:14 #17
Terry > your right :o) ...
Avatar billede eagleeye Praktikant
15. marts 2006 - 09:35 #18
Hvis man syntes join er pænere end "not in (xxxx)" så kan det stadig skrives som en hvis man ønsker det:

SELECT id, navn FROM navn LEFT JOIN (SELECT min(n.id) AS Minid
FROM navn n GROUP BY n.navn HAVING count(n.id) > 1) as qdontsel ON navn.ID = qdontsel.Minid
WHERE qdontsel.Minid is null;
Avatar billede terry Ekspert
15. marts 2006 - 09:40 #19
JOIN will very likley be faster if there are many records
Avatar billede claesdamlund Nybegynder
15. marts 2006 - 23:26 #20
Det udtræk du ønsker at lave er det man i mængdelæren kalder for en differens-sætning, og her er standarden at bruge Not Exists:

SELECT *
FROM tabel AS t1
WHERE NOT EXISTS(
SELECT navn
FROM tabel AS t2
GROUP BY navn
HAVING COUNT(*) > 1 AND Min(id) = t1.id)

I princippet er Not In lige så god, men NOT i kombination med IN sætter eventuelle indekser i din sub-select ud af kraft, og kan dermed "sløve" din forespørgsel - det gør Not Exists ikke.
Ellers er eagleeyes Left Join et glimrende alternativ, bortset fra at "signal-værdien" i den måske ikke er optimal :o)  (når man joiner synes jeg det signalerer et kombineret udtræk fra 2 eller flere tabeller).
Avatar billede vraa Nybegynder
16. marts 2006 - 10:26 #21
eagleeye -> Nedenstående er næsten ved at være der:

SELECT navn, id FROM navn WHERE id not in (SELECT min(n.id) AS Minid
FROM navn n GROUP BY n.navn HAVING count(n.id) > 1);

Hvis den køres på følgende tabel:

ID    Navn
1      Navn1
2      Navn1
3      Navn2
4      Navn2
5      Navn2
6      Navn3
7      Navn3
8      Navn4
9      Navn5

...så får jeg det ønskede udtræk undtagen rækkerne med id 8 og 9. Øverste forekomst ved duplikationer bliver fjernet som ønsket, men den fjerner også rækker hvor der ikke er duplikationer i Navn-kolonnen. De rækker skal også med i udtrækket.

Er det forståeligt?
Avatar billede vraa Nybegynder
16. marts 2006 - 10:30 #22
claesdamlund -> Den du kommer med fjerner alle duplikationer. Den bibeholder fint alle rækker hvor der ikke er duplikationer, men jeg skal have alle rækker med duplikationer(undtagen den øverste forekomst) med i udtrækket.
Avatar billede claesdamlund Nybegynder
16. marts 2006 - 10:38 #23
Ikke forstået. Jeg har lige prøvet at teste den og den udtrækker rækkerne med ID 2,4,5,7,8 og 9.
Var det ikke det du ønskede, eller er der noget jeg har misforstået?
Avatar billede vraa Nybegynder
16. marts 2006 - 10:45 #24
claesdam -> Jeg beklager. Der er en fejl i test tabellen. Den tabel jeg sidder med har ikke en unik ID kolonne. Er det tricky at lave sql sætningen om og få samme udtræk hvis man fjerner ID-kolonnen og kun skal bruge info fra Navn-kolonnen?
Avatar billede claesdamlund Nybegynder
16. marts 2006 - 11:06 #25
Hvordan ved du hvilken forekomst der er den øverste, hvis du ikke har en ID-kolonne?
Avatar billede vraa Nybegynder
16. marts 2006 - 11:06 #26
ved at order by Navn
Avatar billede vraa Nybegynder
16. marts 2006 - 11:08 #27
eller... hvad mener du ?
Avatar billede claesdamlund Nybegynder
16. marts 2006 - 11:13 #28
Hvis du har 3 forekomster der hedder Navn2 vil du have fjernet den øverste af dem? Hvordan ved du hvilken der er den øverste - eller ønsker du bare at fjerne én af dem?
Avatar billede vraa Nybegynder
16. marts 2006 - 11:16 #29
Ja, det er jo så der jeg gerne vil have hjælp. Det er den øverste forekomst der skal fjernes. Kan det ikke gøres på en eller anden måde hvis man sorterer efter Navn?
Avatar billede vraa Nybegynder
16. marts 2006 - 11:23 #30
Hvis man "ORDER BY navn" kan man så ikke på en måde benytte First-funktionen i access til at eliminere den første forekomst ved duplikationer?
Avatar billede claesdamlund Nybegynder
16. marts 2006 - 11:23 #31
Hvis du kun har en navnekolonne ser din tabel vel således ud:

NAVN
Navn1
Navn1
Navn2
Navn2
Navn2
Navn3
Navn3
Navn4
Navn5

Det du ønsker at stå tilbage med er så;

NAVN
Navn1
Navn2
Navn2
Navn3
Navn4
Navn5

Eller?? Hvis det er rigtigt forstået er det vel lige meget hvilken af forekomsterne af Navn2 du får fjernet, så længe du får fjernet én af dubletterne?
Avatar billede vraa Nybegynder
16. marts 2006 - 11:29 #32
Ikke i mit tilfælde. Den test-tabel jeg lavede tidligere er en der minder om den jeg selv sidder med selv. Grunden til at jeg skal have fjernet første forekomst er at i min tabel definerer første forekomst hvad de resterende dupletter hører under. Det er en længere historie, men det er vigitgt for mig og få fjernet den første forekomst.
Avatar billede vraa Nybegynder
16. marts 2006 - 11:54 #33
Jeg er begyndt og forstå hvad du mener :-)

Man skal have en unikt ID-kolonne eller lign. for at kunne fastholde hvad for én række der skal filtreres fra. Det har jeg deværre ikke. Det er en DB tilbage fra midten af 90'erne jeg sidder med og så bare konverteret til access. De tænkte hvis ikke unikke ID kolonner den gang.

Kan det så ikke lade sig gøre eller...?
Avatar billede claesdamlund Nybegynder
16. marts 2006 - 12:14 #34
Så har du efter min bedste overbevisning et problem. Du kan selvfølgelig tilføje en ny kolonne i tabellen med en autonummerering, og dermed hurtigt få oprettet en unik ID for alle dine navne. Det er bare ikke sikkert det vil ske i den rigtige rækkefølge i forhold til den logik du søger.
Men når du skriver at "i min tabel definerer første forekomst hvad de resterende dupletter hører under", så er der vel også et eller andet i tabellen som udpeger den forekomst, som definerer hvad de resterende dubletter hører under?
Avatar billede vraa Nybegynder
16. marts 2006 - 12:26 #35
Jeg har kun en cpr kolonne men heller ikke her er alle felterne udfyldt. Så den er ikke holdbar til fastholde hvilke rækker der skal filtreres fra.
Avatar billede vraa Nybegynder
16. marts 2006 - 12:32 #36
Ved nærmere eftertanke så bruger jeg cpr kolonnen som unik kolonne. Dem der ryger fra må så blive indtastet igen. Har lavet en SQL sætning der virker ud fra det eks. du lavede tidligere.

Læg et svar så får du pointene :-)
Avatar billede claesdamlund Nybegynder
16. marts 2006 - 15:04 #37
Svar...
Avatar billede claesdamlund Nybegynder
16. marts 2006 - 15:05 #38
Prøver igen :o)
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
Dyk ned i databasernes verden på et af vores praksisnære Access-kurser

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