Komplizierte Distinct-Anwendung

dherr

Benutzer
Beiträge
15
Hallo zusammen,
ich habe die folgende Select-Anweisung in meinem Programm (VBnet):
Dim selStrAudioB As String = "SELECT Name, MP3ID, Zuordnung, Dauer, Bytes, " _
+ "CONVERT(VARCHAR(8000), Audio, 1) AS AudioC FROM " + tName10 + " ORDER BY Zuordnung, Name"
Im Detail möchte ich sie nicht erklären, sondern nur das Problem ansprechen:
In der zugehörigen Tabelle gibt es Datensätze mit gleichem "Name" Wert., also ein eventueller Distinct-Fall für die Anzeige der Sätze.
Doch das geht bei dem Aufbau der Select-Anweisung nicht! Denn alle andern Werte im Datensatz müssen angezeigt werden, wie sie in der Anweisung definiert sind.

Sieht jemand eine Möglichkeit, wie man die Dubletten eben nicht anzeigen kann?
Grüße - Dietrich
 
Werbung:
Also du willst pro Namen nur einen Datensatz anzeigen, die anderen Attribute können aber unterschiedlich sein. Du brauchst auf jeden Fall ein Sortier-Kriterium, denn man will ja vermutlich nicht einen zufälligen Datensatz anzeigen, sondern z.B. den mit der längsten Dauer.

Stellt sich die Frage, mit welchem DBMS wir es zu tun haben. Bei den umfangreicheren würde ich sagen mit einer Window-Funktion und einem verschachtelten Select. Etwa so:

Code:
 SELECT * FROM ( SELECT ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Dauer DESC,MP3ID) AS zeile,* FROM tabelle ) t WHERE t.zeile = 1;
 
Hi ukulele, dein select funzt bei mir nicht. Es werden alle Datensätze angezeigt mit Zeilennummer=1, keine Dubletten aussortiert.
Folgendes:
Es sind ein paar Dubletten in der Tabelle enthalten, und die sind im gesamten Datensatz identisch (vermutlich durch eine Fehlfunktion beim Speichern entstanden). Ich versuche eben, einen der doppelten Sätze zu ermitteln und dann zu entfernen. Bin eben beim Ermitteln/Anzeigen nicht weitergekommen.
 
Hmm, dann fehlt noch irgendeine Information. Die Lösung von ukulele funktioniert, die mit Zeilennummer 1 filtern ja genau die Dubletten (=Zeilen mit dem gleichen Namen) aus dem Ergebnis.


(Das ist mit Postgres, sollte aber auch mit SQL Server gehen, nur das ist gerade irgendwie "kaputt" bei dbfiddle)

Vielleicht ist für Dich eine "Dublette" ja etwas anderes als "Zeilen mit dem gleichen Namen". Wenn da noch andere Spalten berücksichtigt werden müssen, dann einfach mit in das PARTITION BY mit aufnehmen.
 
Also mal ein Beispiel.
So sieht die Tabelle (am Anfang) mit ORDER BY Name, MP3ID aus:

MP3ID Zuordnung Name Audio Dauer Bytes
45 Bilder 0281-75 <Binärdaten> NULL 88121
85 Bilder 0281-75 <Binärdaten> NULL 88121
46 Bilder 0756-07 <Binärdaten> NULL 63148
86 Bilder 0756-07 <Binärdaten> NULL 63148
47 Bilder 0756-68 <Binärdaten> NULL 81747
87 Bilder 0756-68 <Binärdaten> NULL 81747
...........
Die Daten zeige ich bspw. in einem Datagridview an.
Nun sollen in einem ersten Schritt von den Dubletten (Name) nur einer der Datensätze gezeigt werden.
Und in einem weiteren Schritt die nicht gezeigten löschen, weil überflüssig (siehe oben - Fehlfunktion).

Grüße - Dietrich
 
Hmm, das SELECT funktioniert soweit ich das beurteilen kann:

Code:
select *
from (
  select mp3id, zuordnung, name, dauer, bytes, row_number() over (partition by name order by mp3id) as zeile
  from dherr
) t
where t.zeile = 1;
liefert
Code:
|mp3id | zuordnung | name    | dauer | bytes|
|------|-----------|---------|-------|------|
|   45 | Bilder    | 0281-75 |       | 88121|
|   46 | Bilder    | 0756-07 |       | 63148|
|   47 | Bilder    | 0756-68 |       | 81747|

Die "überflüssigen" kannst Du z.B. damit löschen:

Code:
delete from dherr
where mp3id in (select mp3id 
                from (
                  select mp3id, row_number() over (partition by name order by mp3id) as zeile
                  from dherr
                ) t
                where t.zeile > 1);
Das ist sicherlich nicht die effizienteste Methode, sollte aber funktionieren.
 
Werbung:
Zurück
Oben