Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Bestimmte Einträge mit Distinct, Group etc filtern

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von Tuesday, 8 März 2013.

  1. Tuesday

    Tuesday Benutzer

    Guten Tag,
    ich habe mein Anliegen bereits im PHP Forum gepostet und wurde mit meinem Problem nun an dieses Forum verwiesen.

    Mein Post aus dem anderen Forum:

    Ich brauche bei folgendem Problem ein wenig Hilfe..

    Ich habe eine Tabelle mit diesem Inhalt:

    Code:
    ID | Wert1 | Wert2
     1 |  1    |  1
     2 |  1    |  1
     3 |  1    |  50        (<---)
     4 |  1    |  50
    
     5 |  9    |  40
     6 |  9    |  1        (<---)
    
     7 |  3    |  1
     8 |  3    |  1
     9 |  3    |  5        (<---)
    
    
    Ich brauche nun ein SQL Statement, welches die Wechsel von Wert2 in der Kombination mit Wert1 rausfiltert und mit die passende ID dazu ausspuckt.
    Wert1 und Wert2 sind nicht fortlaufend, da es nur Schlüssel zu anderen Tabellen sind.
    Über Wert1 findet eine Gruppierung der einzelnen Zeilen statt.

    Also die IDs 3, 6, 9.

    Ausgeführt wird das auf einem Microsoft SQL Server 2008R2.. Wobei ich es jetzt nicht auf ein komplettes SQL Statement abgesehen habe. Ein Ansatz würde mir auch schon reichen.

    Hat jemand eine Idee?


    Die Tabelle ist in der Realität ein wenig komplizierter. Mein Beispiel ist nur eine abstrahierte Darstellung.


    Der Benutzer akretschmer hat freundlicher Weise diesen Lösungsansatz entwickelt.
    Code:
    test=*# select id, wert1, wert2, case when wert2 != lag then '<---' else '' end as info from(select id, wert1, wert2, lag(wert2) over (partition by wert1 order by id) from foo) x;
     id | wert1 | wert2 | info
    ----+-------+-------+------
      1 |     1 |     1 |
      2 |     1 |     1 |
      3 |     1 |     2 | <---
      4 |     1 |     2 |
      5 |     2 |     3 |
      6 |     2 |     4 | <---
      7 |     3 |     5 |
      8 |     3 |     5 |
      9 |     3 |     6 | <---
    (9 rows)
    
    leider unterstützt der SQL Server kein lag().

    Benutzer erc hatte folgende Idee:
    Code:
    SET @a=NULL, @b=NULL;
    SELECT IF(@a!=Wert1,@b:=Wert2,0), IF(@a!=Wert1,@a:=Wert1,0), ID, Wert1, Wert2, IF(@b!=Wert2,'<---','') As info,IF(@b!=Wert2,@b:=Wert2,0) FROM foo ORDER BY ID


    Da das Problem anscheinend tatsächlich ein wenig spezieller ist, nun meine frage an die SQL Profis. Kann mir hier evtl. jemand weiterhelfen?
     
  2. ukulele

    ukulele Datenbank-Guru

    Okay das ist nicht ganz einfach aber eventuell lösbar. Es gibt nur ein paar Dinge, die ich vorher klar stellen möchte.

    a) Du beschreibst einen "Wechsel" in Wert2. Sehe ich das richtig das du damit jede beliebige Veränderung des Wertes meinst sofern Wert1 gleich bleibt?
    b) Wir reden ja hier über ein abstraktes Beispiel. Sind die IDs und Werte in der Realität fortlaufende Integer oder eher UIDs etc.?

    Es ist immer schwer, unterschiedliche Zeilen eines SQL Selects miteinander zu vergleichen, was wir ja tun müssten. Daher müssen wir uns auf jedenfall auf eine Sortierung einigen und dann die Tabelle mit sich selbst joinen nur eben die Datensätze genau um einen versetzt. Nur dann können wir auch Vergleiche anstellen.
     
  3. Tuesday

    Tuesday Benutzer

    Zum Hintergrund:
    Es handelt sich um eine Tabelle, in der eine History/Versionierung für Einträge einer andere Tabelle abgespeichert wird.

    a) Wert1 ist der Schlüssel zu einem Eintrag in der anderen Tabelle, Wert2 beschreibt den Wert eines bestimmten Feldes bzw. dessen Kopie vom anderen Eintrag (beliebige Int)
    b) In der Realität wird über eine Fortlaufende ID (Int) und "Wert1" (Fremdschlüssel zu Eintrag in anderer Tabelle) sortiert.
     
  4. ukulele

    ukulele Datenbank-Guru

    Es sei denn du möchtest die Daten nicht in einem Select sondern per Schleife auslesen. Das ginge auch.
     
  5. Tuesday

    Tuesday Benutzer

    Das Ziel ist das Ziel. Der Weg dahin mein Problem. ;-)

    Es ist egal ob es nur über eine View, Function, Prozedur, ... funktioniert. Hauptsache wir bekommen das gelöst ;-)
     
  6. ukulele

    ukulele Datenbank-Guru

    Was ist denn idealer, eine einzige Ausgabe die alle Unterschiede "markiert" oder ein Script das z.B. eine weitere Tabelle füllt mit Verweisen?
     
  7. Tuesday

    Tuesday Benutzer

    Am liebsten wäre mir eine Ausgabe, die mir die mit (<---) markierten Zeilen ausgibt.
     
  8. ukulele

    ukulele Datenbank-Guru

    Ok das versuch ich mal allerdings krieg ich das nicht so nebenbei gelößt, dazu brauch ich heut Abend oder so mal nen ruhigen Moment :)
     
  9. ukulele

    ukulele Datenbank-Guru

    Ist ja fast schon einfach ;)
    Code:
    SELECT    *,
            (    CASE
                WHEN    t1.wert1 = t2.wert1
                AND        t1.wert2 != t2.wert2
                THEN    '<--'
                END ) AS info
    FROM    (    SELECT    ROW_NUMBER() OVER(ORDER BY id) AS zeile,
                        id,
                        wert1,
                        wert2
                FROM    tabelle ) t1
    LEFT JOIN (    SELECT    ROW_NUMBER() OVER(ORDER BY id) AS zeile,
                        id,
                        wert1,
                        wert2
                FROM    tabelle ) t2 ON t1.zeile = t2.zeile + 1
    Ich habe jetzt doch sicherheitshalber eine Zeilennummer verwendet um Probleme zu vermeiden. Ich weiss natürlich nicht, ob es zu Problemen kommen kann wenn im Hintergrund eventuell während des Selects und dem Join der selben Tabelle in die Tabelle geschrieben wird aber ich glaube das kann nicht passieren. Eigentlich müsste sich das so anwenden lassen.
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden