Henry: mysql Abfrage Doppelte Abgleich mit Ausschluss

Hallo,

Eine Tabelle

id|a    |target|c      |d     |status
1 |rot  |blau  |gelb   |lemon |1     // fällt weg, weil status = 1
2 |bmw  |merc  |audi   |tesla |0
3 |eiche|ahorn |buche  |bambus|1     // fällt weg, weil status = 1
4 |stahl|gold  |silber |platin|1     // fällt weg, weil status = 1
5 |rubin|saphir|smaragd|opal  |0     // fällt weg, weil target gleich wie anderer Eintrag mit status = 1
6 |rubin|ahorn2|rubin  |rubin |0
7 |rubin|gold  |rubin  |rubin |0     // fällt weg, weil target gleich wie anderer Eintrag mit status = 1

Was ist der einfachste Weg alle anzuzeigen deren status != 1 ist aber auch nicht die, deren target-Eintrag denen vom status 1 entspricht?

Also raus kommen sollte nur:
id|a|target|c|d|status
2|bmw|merc|audi|tesla|0
6|rubin|ahorn2|rubin|rubin|0

Gruss
Henry

--
Meine Meinung zu DSGVO & Co:
„Principiis obsta. Sero medicina parata, cum mala per longas convaluere moras.“

akzeptierte Antworten

  1. Hallo Henry,

    habe mal ein paar Leerstellen verteilt, sonst hätte ich Kopfschmerzen bekommen.

    Aber ein bisschen Brumm ist immer noch in der Birne.

    // fällt weg, weil target gleich wie anderer Eintrag mit status = 1

    HÄ? Was soll da wie gleich sein? Bei ID=7 verstehe ich es ja noch, da ist das Gold bei ID=4 mit Status 1 zu finden. Bei ID=5 dagegen bin ich überfordert. Warum ist das auszublenden?

    Solange das nicht klar ist, kann man auch keine Logik formulieren.

    Rolf

    --
    sumpsi - posui - clusi
    1. Hallo Rolf,

      Bei ID=5 dagegen bin ich überfordert. Warum ist das auszublenden?

      upps sry, hast recht muss auch drin bleiben. Also alle deren target nicht bei denen enthalten sind die status 1 haben.

      Gruss
      Henry

      --
      Meine Meinung zu DSGVO & Co:
      „Principiis obsta. Sero medicina parata, cum mala per longas convaluere moras.“
  2. Hi,

    id|a    |target|c      |d     |status
    1 |rot  |blau  |gelb   |lemon |1     // fällt weg, weil status = 1
    2 |bmw  |merc  |audi   |tesla |0
    3 |eiche|ahorn |buche  |bambus|1     // fällt weg, weil status = 1
    4 |stahl|gold  |silber |platin|1     // fällt weg, weil status = 1
    5 |rubin|saphir|smaragd|opal  |0     // fällt weg, weil target gleich wie anderer Eintrag mit status = 1
    6 |rubin|ahorn2|rubin  |rubin |0
    7 |rubin|gold  |rubin  |rubin |0     // fällt weg, weil target gleich wie anderer Eintrag mit status = 1
    

    Was ist der einfachste Weg alle anzuzeigen deren status != 1 ist aber auch nicht die, deren target-Eintrag denen vom status 1 entspricht?

    also erstmal die targets für Status = 1 ermitteln:

    SELECT DISTINCT target FROM tabelle WHERE status = 1
    

    Und jetzt die, die Status != 1 haben, und ein target, das nicht in der Ergebnismenge des 1. Statements ist:

    SELECT * FROM tabelle WHERE status != 1 AND target NOT IN (
        SELECT DISTINCT target FROM tabelle WHERE status = 1
    )
    

    cu,
    Andreas a/k/a MudGuard

    1. Hallo Andreas,

      der SQL Optimizer wird's wohl eh am besten wissen, aber

      • der DISTINCT im inneren SELECT macht unnötigen Aufwand, weil das einen zusätzlichen Schritt in der Verarbeitung bildet
      • eine NOT EXISTS Abfrage wäre vermutlich eh besser

      Rolf

      --
      sumpsi - posui - clusi
      1. Hallo Rolf,

        • der DISTINCT im inneren SELECT macht unnötigen Aufwand, weil das einen zusätzlichen Schritt in der Verarbeitung bildet

        klingt plausibel

        • eine NOT EXISTS Abfrage wäre vermutlich eh besser

        Bin zwar super zufrieden mit der Antwort vom Andreas, aber habe deinen Hinweis mal verfolgt und scheint so zu sein. Ist allerdings ziemlich fachlich erklärt dort und daher nicht so leicht verständlich für mich.

        Gruss
        Henry

        --
        Meine Meinung zu DSGVO & Co:
        „Principiis obsta. Sero medicina parata, cum mala per longas convaluere moras.“
        1. Hallo Henry,

          das bezieht sich auf MS SQL Server und muss für MySQL nicht immer stimmen. Die Aussage zu NULL sollte dir aber zu denken geben, bzw. Du solltest das mal selber durchexerzieren und explains machen.

          Rolf

          --
          sumpsi - posui - clusi
      2. Hi,

        der SQL Optimizer wird's wohl eh am besten wissen, aber

        • der DISTINCT im inneren SELECT macht unnötigen Aufwand, weil das einen zusätzlichen Schritt in der Verarbeitung bildet

        hängt auch von der Anzahl der Zeilen ab, sowie vom Anteil der Zeilen mit Status 1, sowie von der Anzahl unterschiedlicher targets.

        Bei ein paar Hundert Zeilen in der Tabelle ist es vermutlich wurscht.

        • eine NOT EXISTS Abfrage wäre vermutlich eh besser

        s.o. - kommt drauf an.

        cu,
        Andreas a/k/a MudGuard