2012-03-26 3 views
0

Wenn ich meine "Union wählen auswählen", bekomme ich die richtige Anzahl oder Zeilen (156) Ausgeführt unabhängig, wählen Sie # 1 gibt 65 Zeilen und wählen Sie # 2 gibt 138 Zeilen zurück.SQL Server - Einfügen in mit Auswahl und Union - Duplikate werden eingefügt

Wenn ich diese "select union select" mit einem Einfügen in verwenden, bekomme ich 203 Zeilen (65 + 138) mit Duplikaten.

Ich würde gerne wissen, ob es meine Code-Struktur ist, die dieses Problem verursacht?

INSERT INTO dpapm_MediaObjectValidation (mediaobject_id, username, checked_date, expiration_date, notified) 

    (SELECT FKMediaObjectId, CreatedBy,@checkdate,dateadd(ww,2,@checkdate),0 
    FROM dbo.gs_MediaObjectMetadata 
    LEFT JOIN gs_MediaObject mo 
    ON gs_MediaObjectMetadata.FKMediaObjectId = mo.MediaObjectId 
    WHERE UPPER([Description]) IN ('CAPTION','TITLE','AUTHOR','DATE PHOTO TAKEN','KEYWORDS') 
    AND FKMediaObjectId >= 
     (SELECT TOP 1 MediaObjectId 
      FROM dbo.gs_MediaObject 
      WHERE DateAdded > @lastcheck 
      ORDER BY MediaObjectId) 
    GROUP BY FKMediaObjectId, CreatedBy 
    HAVING count(*) < 5 

    UNION 

    SELECT FKMediaObjectId, CreatedBy,getdate(),dateadd(ww,2,getdate()),0 
    FROM gs_MediaObjectMetadata yt 
    LEFT JOIN gs_MediaObject mo 
    ON yt.FKMediaObjectId = mo.MediaObjectId 
    WHERE UPPER([Description]) = 'KEYWORDS' 
    AND FKMediaObjectId >= 
     (SELECT TOP 1 MediaObjectId 
      FROM dbo.gs_MediaObject 
      WHERE DateAdded > @lastcheck 
      ORDER BY MediaObjectId) 
    AND NOT EXISTS 
      (
      SELECT * 
      FROM dbo.fnSplit(Replace(yt.Value, '''', ''''''), ',') split 
      WHERE split.item in (SELECT KeywordEn FROM gs_Keywords) or split.item in (SELECT KeywordFr FROM gs_Keywords) 
      ) 
    ) 

Ich würde schätzen, irgendwelche Hinweise in dieses Problem zu lösen ...

Vielen Dank!

+3

Eine 'SELECT'-Anweisung sollte die gleichen Ergebnisse liefern, wenn sie in' INSERT INTO ... SELECT' verwendet wird. Sind Sie sicher, dass die Abfrage andere Ergebnisse zurückgibt, wenn sie selbst ausgeführt wird, anstatt sie in Ihre Tabelle einzufügen? Das scheint mir nicht möglich zu sein ... –

+0

Ja, ich bin mir sicher, dass die Auswahl & Vereinigung in Ordnung ist. Deshalb frage ich mich, ob es sich um eine Art "Reihenfolge der Operationen" handelt. Aber ich habe nur noch ein paar Tests gemacht, und wenn ich meinen Sproc direkt von SQLServer aus anrufe, ist das Ergebnis nicht in Ordnung, aber wenn ich den Code in einer Abfrage ausfühle, funktioniert es gut. – crichard

Antwort

0

Das UNION-Schlüsselwort sollte nur eindeutige Datensätze zwischen den zwei Abfragen zurückgeben. Wenn ich mich jedoch richtig erinnere, ist dies nur dann der Fall, wenn die Datentypen identisch sind. Die Datumsvariablen könnten das auswerfen. Abhängig vom Kollationstyp können Leerzeichen auch anders behandelt werden. Möglicherweise möchten Sie nach dem Einfügen eine SELECT DISTINCT für die Tabelle dpapm_MediaObjectValidation ausführen, aber achten Sie darauf, Whitespace von beiden Seiten in Ihrem Vergleich zu trimmen. Ein anderer Ansatz besteht darin, Ihre erste Einfügung durchzuführen, dann auf Ihre zweite Einfügung, ganz auf die UNION zu verzichten und eine manuelle EXISTS-Prüfung durchzuführen, um zu sehen, ob die einzufügenden Elemente bereits existieren.

+0

Ich habe meine Sproc geändert, um Ihre zweite Lösung zu verwenden (Existiert mit 2 Einsätzen). Das scheint der Trick zu sein. Weißt du, ob das ein großer Leistungshit ist? – crichard

+0

Normalerweise nicht, wenn der Datensatz, den Sie abfragen, nicht gigantisch ist. Ich persönlich mag es nicht, Tricks wie diese zu verwenden, aber manchmal haben Sie keine Wahl, weil sich die Dinge nicht wie erwartet verhalten. Gemäß dem folgenden stackoverflow-post sollte jedoch die Verwendung des EXISTS-Schlüsselworts selbst dazu beitragen, die Auslastung zu reduzieren -> http://stackoverflow.com/questions/2065329/sql-server-in-vs-exists-performance –