ProgrammatieSQL analist

Hoe unieke records uit een complexe datastructuur met meerdere duplicaten in verschillende kolommen te selecteren, en wat is de specificiteit van het gebruik van DISTINCT versus GROUP BY versus ROW_NUMBER()?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

Het extraheren van unieke records in SQL is een cruciale taak geworden met de massale overstap van organisaties naar het opslaan van multidimensionale gegevens. Soms is het nodig om unieke rijen op basis van een combinatie van verschillende kolommen weer te geven, soms slechts op één sleutel.

Achtergrond van de vraag:

De eerste versies van SQL boden alleen DISTINCT aan voor het filteren van duplicaten. Daarna verschenen er structurele technieken, waaronder GROUP BY voor aggregaties op unieke waardeparen en venstervarianten zoals ROW_NUMBER() voor flexibele scenario's bij het werken met duplicaten, bijvoorbeeld: selectie op de 'laatste' of 'eerste' record.

Probleem:

DISTINCT werkt alleen op het niveau van de velden in SELECT, terwijl GROUP BY aggregaties vereist. Venstervarianten bieden geavanceerde logica, maar het gebruik ervan leidt vaak tot fouten, als de volgorde van rijselectie niet goed wordt nagedacht. Ontwikkelaars verwarren vaak deze benaderingen, wat leidt tot onjuiste resultaten.

Oplossing:

  • Gebruik DISTINCT om unieke rijen op de benodigde velden te verkrijgen.
  • GROUP BY – wanneer aggregaten nodig zijn (bijvoorbeeld de som of datum op unieke paren).
  • Venstervarianten (ROW_NUMBER()) – voor taken van het selecteren van 'één rij uit een groep duplicaten op basis van een criterium'.

Voorbeeldcode:

Een laatste record van bestellingen per klant ophalen:

WITH OrdersRank AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY CustomerID ORDER BY OrderDate DESC) as rn FROM Orders ) SELECT * FROM OrdersRank WHERE rn = 1;

Kernpunten:

  • DISTINCT – retourneert unieke rijen alleen op de velden die in de SELECT zijn opgegeven.
  • GROUP BY – verplicht als aggregatie nodig is.
  • ROW_NUMBER() – extreem flexibel voor selectie van rijen op basis van prioriteit/datum/versie.

Vragen met een addertje onder het gras.

Is het mogelijk om DISTINCT te gebruiken met aggregatiefuncties zonder GROUP BY?

Nee, aggregatiefuncties vereisen groepering, anders is er een syntaxisfout.

SELECT COUNT(DISTINCT CustomerID) -- correct SELECT SUM(Amount), DISTINCT CustomerID -- fout!

Wat gebeurt er als niet alle niet-aggregatievelden uit SELECT in GROUP BY worden opgegeven?

Dit veroorzaakt een fout in de meeste DBMS: alle velden in SELECT, behalve de aggregaten, moeten in GROUP BY worden vermeld.

Kan men duplicaten "verwijderen" met behulp van venstervarianten zonder subquery?

Nee: het gebruik van ROW_NUMBER() binnen dezelfde SELECT filtert niet automatisch "herhalingen", een externe query is nodig om de gewenste rijen te selecteren.

Typische fouten en anti-patterns

  • Gebruik van DISTINCT bij een groot aantal kolommen en rijen – drastische prestatiesnelheid.
  • GROUP BY zonder de benodigde aggregaat – zinloos en resource-intensief.
  • Venstervarianten zonder daaropvolgende filtering – gegevens worden met herhalingen geretourneerd.

Voorbeeld uit het leven

Negatief geval

DISTINCT geselecteerd op alle kolommen voor een tabel van 20 miljoen rijen: de query werkte uren, het resultaat was een time-out of een daling van de databaseprestaties.

Voordelen:

  • Eenvoudig te schrijven.

Nadelen:

  • Zeer ineffectief bij grote gegevens.

Positief geval

Venstervarianten gebruikt: alleen de benodigde laatste registratie per klant in milliseconden verkregen; eerdere en herhalende werden niet geladen.

Voordelen:

  • Hoge prestaties.
  • Flexibiliteit.

Nadelen:

  • Vereist een goede architectuur van de query en kennis van venstervarianten.