Announcement

Collapse
No announcement yet.

Zwei Tabellen zusammenführen?

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

  • Zwei Tabellen zusammenführen?

    Hallo zusammen,
    ich bin mal wieder an den Rand meines begrenzten Wissens angelangt und hoffe, ihr könnt mir helfen.

    Ich habe 2 identische Tabellen (Gruppe_Auftrag und Gruppe_Angebot), diese sollen nun in einer einzigen Tabelle (Gruppe) vereint werden.
    Die 2 Tabellen haben dieselben Spalten (Namen und Typ) und die Daten sind zum größten Teil auch gleich. Aber halt nicht alle.
    Der Primärschlüssel beider Tabellen setzt sich zusammen aus einer ID (kein Autowert, heißt in der Tabelle GruppeIndex) und einem Sprachkenner.
    Die neue Tabelle soll dann 2 weitere Spalten enthalten, die angeben, ob der Datensatz für Aufträge oder Angebote oder für beide gilt. Hier denke ich genügen 2 Spalten vom Typ bit.

    Ich habe eine neue Tabelle erstellt mit den Saplten die benötigt werden
    [highlight=SQL-server]
    CREATE TABLE [dbo].[Gruppe](
    [GruppeIndex] [varchar](10) NOT NULL,
    [Sprachkenner] [varchar](5) NOT NULL CONSTRAINT [DF_Gruppe_Sprachkenner] DEFAULT ('DE'),
    [Typ] [varchar](10) NULL,
    [Text] [varchar](50) NULL,
    [Sortierung] [int] NULL,
    [Angebot] [bit] NULL,
    [Auftrag] [bit] NULL,
    CONSTRAINT [PK_Gruppe] PRIMARY KEY CLUSTERED
    (
    [GruppeIndex] ASC,
    [Sprachkenner] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    [/highlight]

    dann hab ich die Daten aus Gruppe_Angebot hineinkopiert und das bit in der Spalte Angebot auf True gesetzt
    [highlight=SQL-server]
    INSERT INTO [dbo].[Gruppe]
    ([GruppeIndex]
    ,[Sprachkenner]
    ,[Typ]
    ,[Text]
    ,[Sortierung]
    ,[Angebot])
    SELECT [GruppeIndex]
    ,[Sprachkenner]
    ,[Typ]
    ,[Text]
    ,[Sortierung]
    , 1
    FROM [dbo].[Gruppe_Angebot]
    [/highlight]


    Hier hört mein Latein dann jetzt auf.
    Ich muss jetzt die Daten aus Gruppe_Auftrag ebenfalls in die Tabelle Gruppe übertragen.
    Wenn der Datensatz als ganzes schon vorhanden ist, dann soll lediglich das bit Auftrag auf True gesetzt werden.
    Ist die ID schon vorhanden, soll der Datensatz mit einer neuen ID eingefügt werden.
    Ist der Datensatz noch nicht vorhanden, soll er einfach eingefügt werden.

    Kann mir jemand sagen, ob und wie das machen kann?

  • #2
    Hallo Andreas,

    bei den vorhandenen "Gruppen" Datensätzen, die auch als Auftrag vorliegen, das Flag "Auftrag" zu setzen, ist recht einfach: Über den PK joinen; also gibt es den DS in Gruppe und Auftrag =>
    [highlight=SQL]UPDATE dbo.Gruppe
    SET Auftrag = 1
    FROM dbo.Gruppe AS G
    INNER JOIN
    dbo.Gruppe_Auftrag AS A
    ON G.GruppeIndex = A.GruppeIndex
    AND G.Sprachkenner = A.Sprachkenner[/highlight]

    Für die fehlende Datensätze muss man wieder prüfen, ob der PK vorhanden ist oder nicht. Eine Variante wäre über LEFT JOIN und dann auf IS NULL bei der Gruppe prüfen:
    [highlight=SQL]INSERT INTO dbo.Gruppe
    (GruppeIndex
    ,Sprachkenner
    ,Typ
    ,Text
    ,Sortierung
    ,Auftrag)
    SELECT A.GruppeIndex
    ,A.Sprachkenner
    ,A.Typ
    ,A.Text
    ,A.Sortierung
    , 1
    FROM dbo.Gruppe_Auftrag AS A
    LEFT JOIN
    dbo.Gruppe AS G
    ON G.GruppeIndex = A.GruppeIndex
    AND G.Sprachkenner = A.Sprachkenner
    WHERE G.GruppeIndex IS NULL[/highlight]
    Ist nicht getestet, aber immer die Syntax sollte soweit stimmen.
    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
      super, danke. Das hat mich schon viel weiter gebracht.

      Ich habe dein erstes Beispiel so erweitert, das es nur trifft, wenn wirklich jedes Spalte überein stimmt.

      [highlight=SQL-server]
      UPDATE [dbo].[Gruppe] SET [Auftrag] = 1 FROM [dbo].[Gruppe] AS G
      INNER JOIN
      [dbo].[Gruppe_Auftrag] AS A
      ON G.[GruppeIndex] = A.[GruppeIndex]
      AND G.[Sprachkenner] = A.[Sprachkenner]
      AND G.[Typ] = A.[Typ]
      AND G.[Text] = A.[Text]
      AND G.[Sortierung] = A.[Sortierung]
      [/highlight]

      jetzt ist aber in meiner Beispiel-Tabelle die Spalte Sortierung nicht belegt, also jeder Wert NULL. Jetzt bekomm ich als Abfrageergebnis (0 Zeile(n) betroffen)
      Kann ich NULL nicht mit NULL vergleichen?

      Comment


      • #4
        Kann ich NULL nicht mit NULL vergleichen?
        NULL ist ein Sonderfall; ein Vergleich mit = fällt immer negativ aus. Du könntest es auf mehrere Weise ändern.

        AND ISNULL(G.[Sortierung], '') = ISNULL(A.[Sortierung], '')

        AND (G.[Sortierung] = A.[Sortierung]
        OR (AND G.[Sortierung] IS NULL AND A.[Sortierung] IS NULL)
        )

        wobei die letzter Variante formal die richtigere ist; also wirklich auf gleich & gleich geprüft.
        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
          ok, wieder ein Schritt weiter

          Jetzt will ich alle Datensätze am Ende der Tabelle einfügen, wo der Primärschlüssel schon existiert, aber ein anderer Datensatz dargestellt wird.
          Bsp:
          10 | DE | Obst | Apfel | NULL --> Gruppe
          10 | DE | Obst | Birne | NULL ---> Gruppe_Auftrag
          20 | DE | Obst | Kirsche| NULL ---> Gruppe
          20 | DE | Obst | Banane | NULL ---> Gruppe_Auftrag

          Die Birne und die Banane soll dann mit Max(GruppeIndex)+10 eingefügt werden

          [highlight=SQL-server]
          -- alle Datensätze kopieren, die nicht vorhanden sind, der Primär-Schlüssel aber bereits existiert
          -- Es wird einer neuer GruppeIndex generiert
          INSERT INTO [dbo].[Gruppe]
          ([GruppeIndex]
          ,[Sprachkenner]
          ,[Typ]
          ,[Text]
          ,[Sortierung]
          ,[Auftrag])
          SELECT (select max(GruppeIndex)+10 from Gruppe)
          ,A.[Sprachkenner]
          ,A.[Typ]
          ,A.[Text]
          ,A.[Sortierung]
          , 1
          FROM [dbo].[Gruppe_Auftrag] AS A
          INNER JOIN
          [dbo].[Gruppe] AS G
          ON G.[GruppeIndex] = A.[GruppeIndex]
          AND G.[Sprachkenner] = A.[Sprachkenner]
          WHERE G.[Typ] <> A.[Typ]
          OR G.[Text] <> A.[Text]
          OR G.[Sortierung] <> A.[Sortierung]
          OR (G.[Sortierung] IS NULL AND A.[Sortierung] IS NOT NULL)
          OR (G.[Sortierung] IS NOT NULL AND A.[Sortierung] IS NULL)
          [/highlight]

          funktioniert aber leider nur 1 mal.
          Bei der Banane bekomme ich eine Primary-Key-Exception.
          Zuletzt editiert von Andreas Mahr; 09.04.2009, 11:08.

          Comment


          • #6
            Öhm,
            wo der Primärschlüssel schon existiert
            per se ist ein Primary Key Unique; da kannst Du in dem Sinne keine weitere Datensätze einzufügen, die den gleichen PK habe.

            Und zu dem Rest: Sorry, aber das habe ich so nicht verstanden.
            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


            • #7
              weil der PK ja Unique ist muss ich ja einen neuen GruppenIndex generieren, damit der neue PK auch Unique ist.

              Also wieder meine 2 Tabellen die vereint werden sollen:

              Tabelle Gruppe:
              10 | DE | Obst | Apfel | NULL
              20 | DE | Obst | Kirsche| NULL

              Tabelle Gruppe_Auftrag:
              10 | DE | Obst | Birne | NULL
              20 | DE | Obst | Banane | NULL

              Gruppe_Auftrag soll jetzt in Gruppe integriert werden. Die ersten beiden Spalten sind zusammen der PK. Das heißt, wenn ich jetzt einfach den Datensatz von Gruppe_Auftrag nach Gruppe kopiere, bekomme ich eine PK-Verletzung.
              Ich möchte jetzt den Wert der ersten Spalte neu erzeugen, indem ich aus der Tabelle Gruppe den höchsten Wert nehme (hier 20) und 10 dazu zähle. Die Tabellen haben keinen Autowert, da es sonst mit meinem zusammengestzten PK nicht funktioniert, bzw. ich nicht 2 mal den selben Index für verschiedene Sprachen bekommen kann.

              Das Ergebnis sollte dann so aussehn:

              Tabelle Gruppe:
              10 | DE | Obst | Apfel | NULL
              20 | DE | Obst | Kirsche| NULL
              30 | DE | Obst | Birne | NULL
              40 | DE | Obst | Banane | NULL


              Mein Code scheint aber folgendes zu erzeugen:
              Tabelle Gruppe:
              10 | DE | Obst | Apfel | NULL
              20 | DE | Obst | Kirsche| NULL
              30 | DE | Obst | Birne | NULL
              30 | DE | Obst | Banane | NULL

              Das ist natürlich eine verletzung des PK und entsprechend sieht dann auch die Ausgabe aus.

              Comment


              • #8
                ich habs.
                Ohne Schleife komm ich da nicht weiter.

                [highlight=SQL-Server]
                Declare @Index as int
                Declare @GruppeIndex as varchar(10)
                Declare @Sprachkenner as varchar(5)
                Declare @Typ as varchar(10)
                Declare @Text as varchar(50)
                Declare @Sortierung as int
                Declare @STCursor cursor
                Declare @OldIndex as varchar(10)

                set @OldIndex = '0'
                select @Index = max(GruppeIndex) from Gruppe
                set @STCursor = CURSOR LOCAL FOR SELECT A.[GruppeIndex]
                ,A.[Sprachkenner]
                ,A.[Typ]
                ,A.[Text]
                ,A.[Sortierung]
                FROM [dbo].[Gruppe_Auftrag] AS A
                INNER JOIN
                [dbo].[Gruppe] AS G
                ON G.[GruppeIndex] = A.[GruppeIndex]
                AND G.[Sprachkenner] = A.[Sprachkenner]
                WHERE G.[Typ] <> A.[Typ]
                OR G.[Text] <> A.[Text]
                OR G.[Sortierung] <> A.[Sortierung]
                OR (G.[Sortierung] IS NULL AND A.[Sortierung] IS NOT NULL)
                OR (G.[Sortierung] IS NOT NULL AND A.[Sortierung] IS NULL)
                OPEN @STCursor
                FETCH NEXT FROM @STCursor INTO @GruppeIndex,@Sprachkenner,@Typ,@Text,@Sortierung

                WHILE @@FETCH_STATUS = 0
                BEGIN
                if @OldIndex <> @GruppeIndex
                Begin
                set @Index = @Index + 10
                End
                INSERT INTO [dbo].[Gruppe]
                ([GruppeIndex]
                ,[Sprachkenner]
                ,[Typ]
                ,[Text]
                ,[Sortierung]
                ,[Auftrag])
                VALUES(@Index
                ,@Sprachkenner
                ,@Typ
                ,@Text
                ,@Sortierung
                ,1)
                set @OldIndex = @GruppeIndex
                FETCH NEXT FROM @STCursor INTO @GruppeIndex,@Sprachkenner,@Typ,@Text,@Sortierung
                END
                [/highlight]

                Comment

                Working...
                X