none
Suche nach doppelspurig eingetragenen Daten in einer Tabelle RRS feed

  • Allgemeine Diskussion

  • Hallo, ich habe eine Tabelle, in der verschiedene Produkte abgespeichert werden ("Product"). Von jedem Produkt wird jeden Tag ein Exemplar hergestellt und in der Tabelle verzeichnet. Das Herstellungsdatum ("Production") und die Produktkategorie ("Type") sind je in einer anderen Tabelle verzeichnet. In einer weiteren Tabelle ist die Bestellung dieser Produkte verzeichnet. Ich weiss, dass in der Vergangenheit diverse Produkte fälschlicherweise mehrfach verzeichnet worden sind. Ich muss nun eine ID-Liste von verzeichneten Produktexemplaren, bei der ich überprüfen muss, ob diese allenfalls mehrfach verzeichnet sind. Ich habe dazu eine Funktion geschrieben, bei der anhand der ID, das Herstellungsdatum und die Produktkategorie ermittelt wird und mit diesen Angaben dann abgefragt wird, ob es mehrere ID's gibt (es dürfte im korrekten Fall nur eine geben) und wenn ja, wie viele dieser Mehrfachverzeichnungen mit einer Bestellung verknüpft sind:

    Funktion:

    ALTER FUNCTION [dbo].[GetStatus_SameItemWithFileLink] (@PID nvarchar(100))

    RETURNS int

    AS

    BEGIN

    -- Declare the return variable here

    DECLARE @Stat int

    -- Add the T-SQL statements to compute the return value here

    DECLARE @PKat nvarchar(450)

    DECLARE @ID uniqueidentifier

    DECLARE @Date datetime2

    SELECT @PKat=p2.Kat, @Date=t1.Date, @ID=p1.ID FROM Product p1 JOIN Production p2 ON p1.fkProduction=p2.ID JOIN Type t1 ON p1.fkType=t1.ID WHERE p1.PID=@PID

    SELECT @Stat=COUNT(distinct o1.ID) FROM Product p1 JOIN Production p2 ON p1.fkProduction=p2.ID JOIN Type t1 ON p1.fkType=t1.ID JOIN Order o1 ON p1.fkOrder=o1.ID

    WHERE p2.Kat=@PKat

    AND t1.Date=@Date

    AND NOT p1.ID=@ID


    -- Return the result of the function

    RETURN @Stat

    Abfrage:

    SELECT p1.ID, [dbo].[GetStatus_SameItemWithFileLink] (@PID nvarchar(100))

    GetStatus_SameItemWithFileLink

    FROM Product p1

    WHERE p1.ID IN ("Liste der Produkte-ID, die mich interessieren" )

    Ich möchte nun aber nicht nur wissen, wie wie oft Mehrfach-Einträge bestellt worden sind, sondern ich möchte von diesen Bestellungen Angaben haben und zwar folgendermassen:

    1. Spalte: ID eines Produktexemplars

    2. Spalte: ID der fälschlicherweise zusätzlichen Verzeichnung dieses Exemplars

    3. Spalte: Bestelldatum dieser zusätzlichen Verzeichnung

    Wie kann ich diese Abfrage effizient machen? Ich habe mir eine JOIN-Lösung überlegt:

    SELECT ...

    FROM Product p1 JOIN Production pn1 on p1=pn1

    JOIN Type t1 ON p1=t1

    JOIN Production pn2 ON pn1=pn2

    JOIN Type t2 ON t1=t2

    JOIN Product p2 ON pn2=p2

    JOIN Order o2 ON p2=o2

    WHERE p1<>p2

    AND p1 IN ( "Liste der Produkte-ID, die mich interessieren" )

    Die Abfrage klappt. Ich frage mich aber, ob es nicht noch eine effizientere Variante als den JOIN gibt. Vielleicht mit einer stored procedure oder einem Cursor? Könnt ihr mir diese Frage beantworten?

    Danke im Voraus - blumenaa


    Freitag, 27. Oktober 2017 19:11

Alle Antworten

  • Hallo,

    mir ist Deine Frage nicht so richtig klar; was meinst Du mit effizienter? Zudem hast Du hier irgendwie Text doppelt rein kopiert?

    Bitte poste mal das Tabellen Design als DDL, ein paar Beispiel-Daten als DML und das erwartete Ergebnis.


    Olaf Helper

    [ Blog] [ Xing] [ MVP]


    Samstag, 28. Oktober 2017 01:27
  • Doppelte Sätze erkennen:

    Step 1:

    select key1, key2, ..., count(*) from MyTable
    Group by Key1, Key2
    having count(*) > 1

    Damit erhält nun das Ergebnis alle Schlüssel, von denen in den Daten mehr als 1 Satz vorhanden ist.
    Key's können hier sein Product, Production und Type.
    "MyTable" kann sowohl eine einzelne Tabelle als natürlich auch ein Join-Komplex sein.

    Dieses Ergebnis lässt sich nun wiederum mit den originalen Daten verknüpfen:

    select * from MyTable a
    inner join (
    select key1, key2, ..., count(*) from MyTable
    Group by Key1, Key2
    having count(*) > 1
    ) b on a.Key1 = b.Key1 and a.Key2 = b.Key2 ....

    Einer komplexen Prozedur bedarf es dafür nicht.

    Samstag, 28. Oktober 2017 09:45
  • Sorry, mir ist nicht aufgefallen, dass es den Text nochmals kopiert hat. Ich habe mein reales Problem vereinfacht beschrieben. Die Tabellen gibt es so nicht in meiner DB. Mit effizienter habe ich gemeint, ob es eine bessere (sprich weniger rechnungsaufwändige) Methode als den JOIN gibt, wenn man zuerst mit einem Wert (in meinem Fall mit ID's) andere Werte abfragen muss, die dann benötigt werden, um das Resultat zu ermitteln.
    Samstag, 28. Oktober 2017 19:31
  • Hallo bfuerchau, danke für den Tipp. Der Teil mit dem "having" ist eine elegante Methode, um die Mehrfachverzeichnungen zu finden. Der zweite Teil löst aber leider mein Problem nicht. Von den mehrfach vorhandenen Datensätze kenne ich jeweils die ID eines Datensatzes. Ich möchte mir nun aber nicht diesen Datensatz anzeigen lassen, sondern die anderen. Ich kann das in zwei Schritten machen: 1. mit der ID die Werte jener zwei Attribute abfragen, die auch bei den anderen Datensätzen gleich sind. Mit diesen zwei Werten eine zweite Abfrage nach den anderen Datensätzen machen. Meine Frage ist, wie kann ich diese zwei Abfragen in eine verpacken? Ich habe mir dafür die eingangs erwähnte JOIN-Abfrage überlegt, bin mir aber nicht sicher, ob es nicht eine bessere Methode für diese Fragestellung gibt.
    Samstag, 28. Oktober 2017 20:21
  • Die Frage ist, wo stehen die bekannten Id's?
    Kannst du diese in einer weiteren Tabelle ablegen?
    Dann kannst du diese Tabelle im nächsten Schritt anhängen:

    select * from MyTable a
    inner join (
    select key1, key2, ..., count(*) from MyTable
    Group by Key1, Key2
    having count(*) > 1
    ) b on a.Key1 = b.Key1 and a.Key2 = b.Key2 ....

    where not exists (select * from KnowIDs b where a.Id = b.Id)

    Sonntag, 29. Oktober 2017 09:38