Announcement

Collapse
No announcement yet.

zwei Zeilen vergleichen und Unterschiede ausgeben

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

  • zwei Zeilen vergleichen und Unterschiede ausgeben

    Hallo,

    komme bei einer SQL Abfrage in Micorsoft SQL Server Management Studio 2012 nicht weiter.

    Es sollen Werte von Stapeln, die hintereinander stehen, ausgegeben werden bei welchen die Menge, Materialsperre oder ArtikelID nicht übereinstimmen.

    Die Stapel die hintereinander stehen unterscheiden sich anhand der letzten Ziffer: 610102604 1 steht vorne, 610102604 2 steht hinten, dh ich vergleiche, die ersten 9 Ziffern, wenn diese gleich sind und belegt sind, dann muss geprüft werden, ob Menge, Artikel_ID übereinstimmen...
    wenn nicht, müssen die Werte ausgegeben werden.

    ID belegt Menge ArtikelID Materialsperre
    6101026041 1 10 1231 0
    6101026042 1 10 1231 0
    6101019011 1 20 1230 2
    6101019012 1 10 1230 2


    In dem Fall:

    ID belegt Menge ArtikelID Materialsperre

    6101019011 1 20 1230 2
    6101019012 1 10 1230 2

    Die 1. Schwierigkeit ist, dass die Werte, die ich brauche aus 8 verschiedenen Tabellen selektiert werden muss.
    Die 2. Schwierigkeit ist, die ID zu vergleichen und die unterschiede auszugeben...

    Hoffe, ich konnte mich deutlich ausdrücken...

    Vielen Dank für eure Hilfe

  • #2
    Ist Id ein Zahlentyp oder ein string?
    Kann an der letzten Stelle auch was anderes stehen als 1 und 2?

    Comment


    • #3
      Ist ein nvarchar (10).
      An der letzten Stelle kann nur eine 1(vorne) oder eine 2(hinten) stehen.

      Comment


      • #4
        [HIGHLIGHT=SQL]select Stapel1.ID, Stapel1.belegt, Stapel1.Menge, Stapel1.ArtikelID, Stapel1.MaterialSperre
        from DeineLiebeTabelle Stapel1
        inner join DeineLiebeTabelle Stapel2 on SUBSTRING(Stapel1.ID,1,9) = SUBSTRING(Stapel2.ID,1,9) and Stapel1.ID != Stapel2.ID
        where Stapel1.belegt != Stapel2.belegt
        or Stapel1.Menge != Stapel2.Menge
        or Stapel1.ArtikelID != Stapel2.ArtikelID
        or Stapel1.MaterialSperre != Stapel2.MaterialSperre[/HIGHLIGHT]

        Comment


        • #5
          MSSql Server bietet 2 Mengen Befehle namens EXCEPT und INTERSECT, die eine "Un"Menge und eine Schnittmenge liefern.
          Meine Strategie wäre:
          a) Ein SQL Statement oder besser View definieren
          1. über alle deine 8 Tabellen
          2. mit allen Feldern die relevant für den vergleich sind (oder sein könnten, denn u.U. "tun sie nicht weh"*).
          und dann
          b) Das Ergebnis von a) via Except und/oder Intersect abzufragen und dabei mit
          1. mit groben Kategorien zu beginnen (wenig Felder)
          2. immer mehr Felder hinzunehmen (bis zu den ID/PK)

          b) entspricht dabei dem Teil von Ralf Jansen, der eine Tabelle (mein Schritt a) mit sich selbst joined.
          Minus und Intersect benötigen aber keine explizite Angaben einer Where Bedingung. Es wird jedes Feld des Select verglichen. Das impliziert, das beide Tabellen identisch aufgebaut sind. Verwendet man 2 mal die gleiche Tabelle, ergibt sich das aber automatisch.
          Man kann also bequem wie unter b) vorgeschlagen mit mehr oder weniger Feldern "spielen" und die Ergebnisse verfeinern, verstehen, verarbeiten.

          Ob man mit Except oder Interesect noch spezifsche Where Bedingungen einsetzt, um z.B. nur bestimmte Artikelgruppen zu vergleich, einzelne Sätze auszuschließen usw. ist einem natürlich freigestellt.

          Hier habe ich ein nettes Beispiel gefunden, das auch wirklich mit mehreren Spalten arbeitet, statt nur mit 1 oder 2 und dann "nur" als
          Code:
          Not In
          Ersatz verwendet wird.
          http://www.mssqltips.com/sqlserverti...ct-and-except/


          * Sind in der Basistabelle / -View / -SQL Statement mehr Felder, als am Ende benötigt, kann das evtl. sogar von Vorteil sein. Es sollten natürlich nicht stark variierende Felder sein, wie ID oder Create Date usw., aber jegliche Art von Kategorien sind da praktisch, um Gruppen zu bilden oder auszuschließen. Was auch immer vorhanden ist, im konkreten EXCEPT oder INTERSECT Statement, kann man alles weglassen, was einen akut nicht interessiert.
          Gruß, defo

          Comment


          • #6
            Vielen Dank für die Antworten, aber leider bekomme ich nicht das gewünschte Ergebnis.

            Hier ist mein Coding:
            [highlight=sql]
            select
            a.lagerplatz_ID 'Fach'
            ,A.Belegt As 'Belegt'
            ,A.Gesperrt As 'Fachsperre'
            ,A.Sperrgrund As 'FachSperrgr.Nr.'
            ,SperrP.SperrgrundPosition_Kurztext As 'FachSperrgrund Fach'
            ,St.Fertigungsauftragsnummer As 'Fertigungsauftrag'
            ,St.Stapelnummer As 'Stapelnummer'
            ,SchonPL.SchonerplattenID As 'SchonerplattenID'
            ,St.Schonerplattenstapel As 'SP'
            ,St.Artikel_ID As 'MatNr'
            ,SAP.MAKTX As 'MatTXT'
            ,St.BC_Granulat_Chargennummer As 'Charge'
            ,St.Menge As 'Menge'
            ,St.Sperrgrund As 'Matsperre'
            ,SperrM.SperrgrundMaterial_Kurztext As 'Matsperrtxt'
            ,A.sperrgrund as 'Sperrgrund'
            ,convert (nvarchar(30), St.Einlagerzeitpunkt, 104) as 'Einlagerdatum'
            ,convert (nvarchar(30), St.Produktionszeitpunkt, 104) as 'Produktionsdatum'
            ,A.Gesperrt As 'MatsperrBit'
            ,St.Gesperrt As 'StapelsperrBit'


            from mf_61_lagerspiegel A inner join MF_HFT_Stapel St
            on A.Fertigungsauftragsnummer = St.Fertigungsauftragsnummer
            and A.Stapelnummer = St.Stapelnummer
            left Join SAP_Materialstamm SAP
            on St.Artikel_ID = CAST(MatNr As INT)

            left join MF_Schonerplatten SchonPL
            on st.Fertigungsauftragsnummer = SchonPL.AktFertigungsauftragsnummer
            and st.Stapelnummer = Schonpl.AktStapelnummer


            left Join MF_Sperrgruende_Material SperrM
            ON St.Sperrgrund = SperrM.SperrgrundMaterial_ID

            left Join MF_Sperrgruende_Position SperrP
            On A.Sperrgrund = SperrP.SperrgrundPosition_ID

            where (
            A.Lagerplatz_ID like '%2'
            and belegt = 1
            and exists (Select * from MF_61_LagerSpiegel where substring(A.Lagerplatz_ID,1,9) +'1' = Lagerplatz_ID and belegt =1)
            )
            or
            (
            A.Lagerplatz_ID like '%1'
            and belegt = 1
            and exists (Select * from MF_61_LagerSpiegel where substring(A.Lagerplatz_ID,1,9) +'2' = Lagerplatz_ID and belegt =1)
            )

            order by a.Lagerplatz_ID
            [/highlight]

            Hier muss jetzt verglichen werden, ob die ersten 9 Stellen des Lagerplatz_IDs übereinstimmen, dann müssen die Werte von Lagerplatz_ID mit der Endung 1 mit der Lagerplatz_ID mit der Endung 2 verglichen werden; wenn Menge, Materialnummer (Artikel_ID) nicht gleich sind, sollen die Werte ausgegeben werden
            Zuletzt editiert von gfoidl; 19.06.2015, 13:10. Reason: Code-Tags hinzugefügt.

            Comment


            • #7
              So auf den ersten Blick würde ich mal die Frage in den Raum stellen, ob die Operation substring(A.Lagerplatz_ID, 1, 9) + '2' das produziert, was Du möchtest.
              Soll 2 addiert werden oder soll '2' konkateniert werden?

              Außerdem ist bei Deinem letzten Post gar nicht klar, was nun überhaupt das Ergebnis Deines Statements ist bzw. das Problem. Gibt es eine Fehlermeldung, zuviel, zuwenig Datensätze?
              Gruß, defo

              Comment


              • #8
                hallo defo,

                '2' soll konkateniert werden.

                Mit meiner Abfrage erhalte ich ein Ergebnis. Ein Auszug hiervon wäre:

                Fach Belegt Matnr Menge
                6101044021 1 1234 10
                6101044022 1 1234 8
                6101044031 1 1235 5
                6101044032 1 1235 5

                Allerdings soll in der Liste nur Werte auftauchen, bei denen die Menge, oder Materialnummer sich unterscheiden.

                Also nur:
                Fach Belegt Matnr Menge
                6101044021 1 1234 10
                6101044022 1 1234 8


                Mein Problem ist es Fach 6101044021 und 6101044022, die in den ersten 9 Stellen miteinander übereinstimmen, zu vergleichen und auszugeben, wenn Materialnummer oder Menge nicht übereinstimmen.
                Diesen Vergleich bekomme ich nicht hin.

                Comment


                • #9
                  Originally posted by Miyako View Post
                  Fach Belegt Matnr Menge
                  6101044021 1 1234 10
                  6101044022 1 1234 8
                  6101044031 1 1235 5
                  6101044032 1 1235 5
                  Ok, das ist doch ein Ansatz. Hab ich das richtig verstanden, dass der Unterschied jeweils zwischen der "Gruppe" %1 und %2 abgefragt werden soll?
                  Bau das SQL so, dass genau diese Menge oben rauskommt ohne irgendwelche Einschränkungen (also was Du am Ende des Statements oben EXISTS ... or ..EXISTS gemacht hast).
                  Nimm zusätzlich die Felder substring(Fach,1,9) as Fach19 und substring(Fach,10,1) as Fach10 rein.

                  Das Ganze am besten als View definieren.
                  dann:
                  select Fach19, Belegt, Matnr, Menge from MySpezialSelect where Fach10=1
                  except
                  select Fach19, Belegt, Matnr, Menge from MySpezialSelect where Fach10=2

                  damit erhälst Du alle 1er mit abweichenden Daten zu 2ern.
                  Gruß, defo

                  Comment


                  • #10
                    Hallo Defo,

                    1000 Dank für Deine Hilfe!

                    Leider bekomme ich immer einen Syntaxfehler, den ich nicht finden kann:

                    create view Unterschiede AS
                    select a.lagerplatz_ID As 'Fach'
                    ,substring (a.lagerplatz_ID,1,9) as 'Fach19'
                    ,Substring (a.Lagerplatz_ID,10,1) as 'Fach10'
                    ,A.Belegt As 'Belegt'
                    ,A.Gesperrt As 'Fachsperre'
                    ,A.Sperrgrund As 'FachSperrgr.Nr.'
                    ,SperrP.SperrgrundPosition_Kurztext As 'FachSperrgrund Fach'
                    ,St.Fertigungsauftragsnummer As 'Fertigungsauftrag'
                    ,St.Stapelnummer As 'Stapelnummer'
                    ,SchonPL.SchonerplattenID As 'SchonerplattenID'
                    ,St.Schonerplattenstapel As 'SP'
                    ,St.Artikel_ID As 'MatNr'
                    ,SAP.MAKTX As 'MatTXT'
                    ,St.BC_Granulat_Chargennummer As 'Charge'
                    ,St.Menge As 'Menge'
                    ,St.Sperrgrund As 'Matsperre'
                    ,SperrM.SperrgrundMaterial_Kurztext As 'Matsperrtxt'
                    ,A.sperrgrund as 'Sperrgrund'
                    ,convert (nvarchar(30), St.Einlagerzeitpunkt, 104) as 'Einlagerdatum'
                    ,convert (nvarchar(30), St.Produktionszeitpunkt, 104) as 'Produktionsdatum'
                    ,A.Gesperrt As 'MatsperrBit'
                    ,St.Gesperrt As 'StapelsperrBit'


                    from mf_61_lagerspiegel A inner join MF_HFT_Stapel St
                    on A.Fertigungsauftragsnummer = St.Fertigungsauftragsnummer
                    and A.Stapelnummer = St.Stapelnummer
                    left Join SAP_Materialstamm SAP
                    on St.Artikel_ID = CAST(MatNr As INT)

                    left join MF_Schonerplatten SchonPL
                    on st.Fertigungsauftragsnummer = SchonPL.AktFertigungsauftragsnummer
                    and st.Stapelnummer = Schonpl.AktStapelnummer


                    left Join MF_Sperrgruende_Material SperrM
                    ON St.Sperrgrund = SperrM.SperrgrundMaterial_ID

                    left Join MF_Sperrgruende_Position SperrP
                    On A.Sperrgrund = SperrP.SperrgrundPosition_ID

                    where (
                    A.Lagerplatz_ID like '%2'
                    and belegt = 1
                    and exists (Select * from MF_61_LagerSpiegel where substring(A.Lagerplatz_ID,1,9) +'1' = Lagerplatz_ID and belegt =1)
                    )
                    or
                    (
                    A.Lagerplatz_ID like '%1'
                    and belegt = 1
                    and exists (Select * from MF_61_LagerSpiegel where substring(A.Lagerplatz_ID,1,9) +'2' = Lagerplatz_ID and belegt =1)
                    )
                    --where
                    --(A.Lagerplatz_ID like '%2'and belegt = 1 and st.artikel_id)
                    --<>
                    --(A.Lagerplatz_ID like '%1'and belegt = 1 and st.artikel_id)

                    select <-- Hier soll der Fehler sein
                    Fach19
                    ,Belegt
                    ,MatNr
                    ,Menge
                    from Unterschiede
                    where Fach10 = 1
                    except
                    select
                    Fach19
                    ,Belegt
                    ,MatNr
                    ,Menge
                    from Unterschiede
                    where Fach10 = 2

                    -- order by a.Lagerplatz_ID


                    Vielen Dank noch mal für die Hilfe...

                    Comment


                    • #11
                      Mmh, der Fehler will aber aus Datenschutzgründen anonym bleiben?
                      Ich kenne keine RDBMS, das nicht wenigstens eine Fehlernummer liefert, die meisten geben auch Zeile, Spalte aus.

                      Ich bin kein SQL Parser, kenne Dein Datenmodell nicht, geschweige Deine Daten und sehe auch keinen Sinn, den fifty fifty joker zu ziehen.

                      Werd mal bitte etwas konkreter.

                      Ach und für den Fall, dass Du das Buchstabe für Buchstabe so eingespielt hast, wie es dort steht, versuch mal ein Semicolon zwischen den einzelnen Statements. Das mögen die meisten Systeme ganz gerne, wenn mehr als ein Befehl abgesetzt wird.
                      Und für den Fall, dass Du mehr Mitleser und Unterstützer gewinnen willst. Es gibt Code Tags, mit denen speziell die SQL Statements aufgehübscht werden können. Außerdem gibt es noch SQL Online Formatierer- falls Deine IDE das nicht kann-, die alles schön einrücken und umbrechen. Ein derart behandeltes SQL Statement kann ungemein hilfreich sein, wenn man seinen eigenen Code nicht entziffern kann.
                      Gruß, defo

                      Comment

                      Working...
                      X