Announcement

Collapse
No announcement yet.

Primärschlüssel Problem

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Primärschlüssel Problem

    Hallo Leute,

    ich muss eine Portierung per SQL-Befehle durchführen von einer alten Datenbank ohne Primärschlüssel in eine Datenbank mit Primärschlüssel. In der alten Datenbank sind anhand der Schlüssel der neuen Datenbank Duplikate vorhanden. Ich habe mal folgendes einfaches Beispiel aufgestellt:

    Tabelle test:

    prim1 prim2 field1 field2
    1 1 1 1
    1 1 1 1
    1 1 1 0
    1 2 1 0
    2 1 1 0

    Die Spalten prim1 und prim2 bilden in der neuen Datenbank einen zusammengesetzten Primärschlüssel. Beim Übertragen der Tabelle müssen zwingend 2 Zeilen mit dem Primärschlüssel 1 1 wegfallen. Die Entscheidung sollte mir am besten SQL abnehmen.
    Ich habe mir mit folgendem Trick (Benutzung der Agregatfunktion Max()) Abhilfe geschaffen:
    SELECT prim1, prim2, MAX(field1) as field1, MAX(field2) as field2 FROM test GROUP BY prim1, prim2

    Dabei ist es mir egal, ob ich die Zeile 1 1 1 1 oder die Zeile 1 1 1 0 behalte.
    Gibt es ein SQL-Statement, welche mir die Entscheidung abnimmt, welche der beiden Zeilenwerte ausgewählt wird?

    Vielen Dank im Voraus!

    Gruß

    maddilli16

  • #2
    Wenn es Dir egal ist, welche Zeile genommen werden soll; wie soll den dann die Entscheidung aussehen (Min, Max, Avg, Gerade/Ungerade, Farbe, Uhrzeit,...) ?
    Olaf Helper

    <Blog> <Xing>
    * cogito ergo sum * errare humanum est * quote erat demonstrandum *
    Wenn ich denke, ist das ein Fehler und das beweise ich täglich

    Comment


    • #3
      Zum Beispiel immer die erste Zeile. In meinem Beispiel die 1 1 1 1.
      Ich arbeite mit einer Ingres Datenbank. Da gibt es leider keine Limit Funktion. Sonst hätte man dieses z.B. mit der Funktion lösen können.

      Comment


      • #4
        Doch, gibt es scheinbar schon, nur das Limit bei Ingres FIRST heisst, siehe:
        http://docs.ingres.com/sqlref/Selectinteractive

        Mit entsprechenden SubSelects bekommst Du es dann hin (ich hoffe mal für Dich, die Tabelle hat nicht zu viele Felder, sonst vie Spass beim Tippen).

        Mit den Aggregat-Funktion jedenfalls bekommst so Du eigentlich gar keinen der vorhandenen Datensätze, sondern nur einen Mix.

        Wenn Du die Quell-Tabelle ändern kannst & darfst, dann füg eine Sequence ein, das macht es viel leichter.
        Olaf Helper

        <Blog> <Xing>
        * cogito ergo sum * errare humanum est * quote erat demonstrandum *
        Wenn ich denke, ist das ein Fehler und das beweise ich täglich

        Comment


        • #5
          ui. Vielen Dank! Das habe ich wohl überlesen!!!!
          Nur habe ich noch nicht ganz verstanden, wie ich mit der Anweisung einen OFFSET definieren kann!? Also wähle die Zeilen 7 bis 20 vom ResultSet.

          Das das ein Mix war ist mir klar. Wusste mir aber momentan nicht weiter zu helfen.

          Noch eine Frage zu DISTINCT:
          Wenn ich 2 identische Zeilen habe mit der tid 1 und 2, welche der beiden Zeilen wird dann ausgewählt. Gibt es da eine Regel, die immer gilt?

          Comment


          • #6
            Ist ja egal, da die Zeilen ja identisch sind

            Comment


            • #7
              OFFSET
              Mit First bekommst Du keinen Offset "mittendrin", sondern nur die ersten 1-n Datensätze zurück geliefert.
              Einige DBMS haben eine Funktion für eine laufende Zeilennummer, mit der man ein solchen Offset selektieren kann.
              Die Funktionen heissen RowId oder RowCount, je nach DBMS.
              Ob es das bei Ingres auch gibt, weiß ich nicht (ich kenne Ingres nicht) und in der Doku läßt es sich nicht so gut suchen.

              Das mit dem FIRST wie ich es mir vorstellen könnte, sieht so aus
              [highlight=SQL]
              SELECT prim1, prim2,
              (SELECT FIRST 1 field1 FROM test AS S
              WHERE m.prim1 = s.prim1 AND m.prim2 = s.prim2) AS field1,
              (SELECT FIRST 1 field2 FROM test AS S
              WHERE m.prim1 = s.prim1 AND m.prim2 = s.prim2) AS field2
              FROM test AS M
              GROUP BY prim1, prim2
              [/highlight]
              Jetzt muß Du Dir nur noch überlegen, was den der "Erste" sein soll => ORDER BY in den Subselects


              DISTINCT
              Mit dem Ausdruck werden nur eindeutige Datensätze zurückgeliefert, abhängig von den Selektierten Feldern.

              Angewendet auf Dein obiges Beispiel bekommst Du dann mit

              SELECT DISTINCT prim1 prim2 field1 field2
              FROM test

              als Ergebnis:

              prim1 prim2 field1 field2
              1 1 1 1
              1 1 1 0
              1 2 1 0
              2 1 1 0

              der zweite Datensatz wird also unterdrückt, da er identisch mit dem ersten ist.
              Ich weiß jetzt nicht, was "tid" bei Dir ist, aber wenn es eine Sequence/Identity ist und Du sie mitselektierst, bekommst Du alle Datensätze, das das Ergebnis keine Doublette aufweißt.
              Olaf Helper

              <Blog> <Xing>
              * cogito ergo sum * errare humanum est * quote erat demonstrandum *
              Wenn ich denke, ist das ein Fehler und das beweise ich täglich

              Comment


              • #8
                Die FIRST Anweisung funktioniert leider nicht in Subselects. Nur im ersten Select Statement.
                Weiß jemand, wie man das RowCount-Konzept(in ingres dürfte das iirowcount sein) in einem Select-Statement benutzen kann?

                Comment


                • #9
                  Die FIRST Anweisung funktioniert leider nicht in Subselects. Nur im ersten Select Statement
                  Skurill.

                  Laut Docu
                  http://docs.ingres.com/sqlref/Unders...sionsandEvents
                  liefert Dir iirowcount die Anzahl der zuletzt geänderten Datensätze, ist also was anderere.

                  Wenn es sowas wie die RowID gibt, kannst Du sie ganz einfach verwenden:

                  SELECT *
                  FROM Tabelle
                  WHERE RowID() BETWEEN 7 AND 20

                  liefert dann die Zeilen zwischen 7 und 20
                  Olaf Helper

                  <Blog> <Xing>
                  * cogito ergo sum * errare humanum est * quote erat demonstrandum *
                  Wenn ich denke, ist das ein Fehler und das beweise ich täglich

                  Comment


                  • #10
                    Das löst leider alles nicht mein Problem. Hab jetzt schon die verschiedensten abfragen ausprobiert. Leider ohne gewünschten erfolg.
                    Das einzige was ich gefunden habe in der Doku ist die tid. Jede Zeile einer Datenbanktabelle bekommt eine eindeutige tid in einer Ingres Datenbank. Das scheint aber leider auch nicht so ganz zu funktionieren.
                    Hat noch irgendjemand eine ander Idee, was ich ausprobieren könnte?

                    Comment


                    • #11
                      Hi,

                      dann versuchs mal so:

                      Select Tabelle.prim1,Tabelle.prim2,Tabelle.field1,Tabelle .field2 from Tabelle
                      Where Tabelle.Tid=
                      (select min(t2.tid) from Tabelle t2 where
                      Tabelle.prim1=t2.prim1
                      And Tabelle.prim2=t2.prim2)

                      Gruß
                      docendo discimus

                      Comment


                      • #12
                        Danke an alle.
                        Der letzte Beitrag hat funktioniert und reicht für meine Zwecke!!!

                        Gruß

                        Comment

                        Working...
                        X