Announcement

Collapse
No announcement yet.

Hilfe bei Abfrage

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

  • Hilfe bei Abfrage

    Hallo,

    angenommen, ich habe eine Kunden-Tabelle und eine weitere Tabelle mit Ansprechpartnern zu den Kunden, verbunden über eine KundenNr. Nun möchte ich eine Auswertung aller Kunden haben, in der, wenn vorhanden, auch ein Ansprechpartner vermerkt ist. Dafür bietet sich wohl ein LEFT JOIN an; mein Problem jedoch: habe ich mehrere Ansprechpartner zu dem Kunden, erscheint auch der Kunde zweimal in der Auswertung. Das soll aber nicht sein, ich will einfach dann den ersten Ansprechpartner haben. Wie kriege ich das hin? Mir fällt nur folgendes ein:

    SELECT kunden.*, (SELECT TOP 1 Name FROM Ansprechp WHERE kndnr = kunden.kndnr) AS AP_Name FROM kunden

    Aber ich denke mal, das ist nicht sehr performant, geschweige denn der Aufwand, wenn man mehrere Felder aus der Ansprechp braucht. Wie macht man sowas cleverer?

    Danke für Eure Tipps ...

    Dave

  • #2
    Originally posted by Dave_Bowman View Post
    Hallo,

    angenommen, ich habe eine Kunden-Tabelle und eine weitere Tabelle mit Ansprechpartnern zu den Kunden, verbunden über eine KundenNr. Nun möchte ich eine Auswertung aller Kunden haben, in der, wenn vorhanden, auch ein Ansprechpartner vermerkt ist. Dafür bietet sich wohl ein LEFT JOIN an; mein Problem jedoch: habe ich mehrere Ansprechpartner zu dem Kunden, erscheint auch der Kunde zweimal in der Auswertung. Das soll aber nicht sein, ich will einfach dann den ersten Ansprechpartner haben. Wie kriege ich das hin? Mir fällt nur folgendes ein:

    SELECT kunden.*, (SELECT TOP 1 Name FROM Ansprechp WHERE kndnr = kunden.kndnr) AS AP_Name FROM kunden

    Aber ich denke mal, das ist nicht sehr performant, geschweige denn der Aufwand, wenn man mehrere Felder aus der Ansprechp braucht. Wie macht man sowas cleverer?

    Danke für Eure Tipps ...

    Dave
    Mach das SELECT im LEFT JOIN...

    Code:
    SELECT K.*,  A.AP_Name 
    FROM kunden AS K
    LEFT JOIN (SELECT TOP 1 Name AS AP_Name, Kdnr FROM Ansprechp ) AS A
                ON A.kndnr = K.kndnr

    Comment


    • #3
      Nee, irgendwie funktioniert das nicht. Ich habe dann bei den Ansprechpartnern zwar nur eine Zeile, die aber komplett mit NULL gefüllt ist.

      Konkret mein Versuch:
      Code:
      SELECT kunden.kndnr, kunden.name, ka.Name AS AP_Name FROM kunden 
      LEFT JOIN (SELECT TOP 1 kndnr, Name FROM kunden_ansprech) ka ON kunden.kndnr = ka.kndnr AND ka.funktion LIKE '%techni%' 
      WHERE kunden.kndnr = 10861
      Tatsächlich gibt es aber vier technische Ansprechpartner. Kann es sein, dass dieses Konstrukt nicht mit dem SQL Server 2000 funktioniert?

      Comment


      • #4
        Eigentlich sollte der Parser/Optimizer so clever sein und den schnellsten Weg finden, wenn du ihm konkret sagst, was du möchtest. Insofern finde ich dein gleich am Anfang gezeigtes Statement schon okay und würde das so lassen. Wenn aber zB kein Index auf der Kundennummer in der Anprechpartner-Tabelle liegt, dann wäre das performancemäßig der Oberbremser, sowas könntest du mit dem besten Statement nicht ausbügeln.

        bye,
        Helmut

        Comment


        • #5
          Ok, dann lass ich das mal so. Danke für die Rückmeldung. Ich hätte angenommen, da gibt es einen schicken Kniff, wie man das eleganter macht. Denn brauche ich viele Felder aus der gejointen Tabelle, dann habe ich eben auch viele eigenständige, vollständige SELECTs da stehen, die ich ja, um sicher zu gehen, dass alle SELECTs auch denselben Datensatz holen, nach irgendeinem eindeutigen Merkmal sortieren lassen muss. Hast schon recht, performancemäßig hatte ich schlimmeres befüchtet, aber ich brauchte halt diesmal nur drei Felder, und ich dachte wie gesagt, es gibt besser Formuliertes.

          Naja, Danke für Eure Tipps und Hinweise ...

          Dave

          Comment


          • #6
            Hallo Ebis, hallo Dave

            [highlight=SQL]SELECT K.*, A.AP_Name
            FROM kunden AS K
            LEFT JOIN (SELECT TOP 1 Name AS AP_Name, Kdnr FROM Ansprechp ) AS A
            ON A.kndnr = K.kndnr[/highlight]
            Da ist ein kleiner Gedankenfehler drin; die Derivated Table liefert durch das Top 1 nur einen einzigen Datensatz zurück; unabhängig vom Kunden, den der Join findet ja erst ausserhalb statt.

            Es geht, wenn die Ansprechpartner ebenfalls eine eigene ID haben, in meinem Beispiel mal die "Nummer".
            Min(Nummer) für den ersten AnsprP (fortlaufende Nr mal angenommen), min Max würde man den letzten bekommen.

            [highlight=SQL]SELECT K.*, A.*
            FROM kunden AS K
            LEFT JOIN
            Ansprechp AS A
            ON A.kndnr = K.kndnr
            AND A.Nummer = (SELECT Min(Nummer)
            FROM Ansprechp AS SUB
            WHERE SUB.kndnr = K.kndnr)[/highlight]
            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
              Stimmt, das sollte funktionieren, Danke. Wenn auch nicht in meinem Fall, da gibt es als Primärschlüssel einen UniqueIdentifier, und der mag kein MAX oder MIN. Aber an sich ist es das, was ich gesucht habe. Im Grunde müßte doch auch

              Code:
              ...LEFT JOIN Ansprech AS A ON A.kndnr = K.kndnr
              AND A.Nummer IN (SELECT Min(Nummer) FROM Ansprechp GROUP BY kndnr)
              funktionieren.

              Muss ich bei Gelegenheit mal ausprobieren, aber wie gesagt, ich habe halt UniqueIdentifiers. Danke dennoch ...

              Edit: Und es geht doch, indem man den UniqueIdentifier in einen String umwandelt, also
              ... AND CONVERT(varchar(36), A.rowguid) IN (SELECT MAX(CONVERT(varchar(36), rowguid)) FROM Ansprech GROUP BY kndnr)

              Müsste doch gehen ...

              Comment


              • #8
                Auch kein Problem, dann wieder zurück zu TOP 1
                [highlight=SQL]SELECT K.*, A.*
                FROM kunden AS K
                LEFT JOIN
                Ansprechp AS A
                ON A.kndnr = K.kndnr
                AND A.Nummer = (SELECT TOP 1 Nummer
                FROM Ansprechp AS SUB
                WHERE SUB.kndnr = K.kndnr)[/highlight]
                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

                Working...
                X