tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
10
ZUGRIFFE
373
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    xrax xrax ist offline Mitglied Gold
    Registriert seit
    Oct 2004
    Beiträge
    133
    Hallo zusammen,

    ich habe folgende Tabelle die real > 5 Mio. Zeilen hat.

    MyTab:

    Nr name
    1 ABC
    2 ABC
    3 ABC
    4 ABC
    2 DEF
    5 DEF
    3 GHI
    5 GHI

    Mit

    Code :
    1
    
    SELECT * FROM MyTab ORDER BY Nummer
    erhalte erwartungsgemäß

    Nr name
    1 ABC
    2 ABC
    2 DEF
    3 ABC
    3 GHI
    4 ABC
    5 DEF
    5 GHI

    Ich möchte aber die Einträge mit den Nummern die mit DEF ein Tupel bilden nicht erhalten. Nicht nur die nicht, welche name=DEF sind.

    Also als ergebniss:

    Nr name
    1 ABC
    3 ABC
    3 GHI

    2|ABC und 5|GHI nicht, wegen 2|DEF und 5|DEF

    Wie sieht hierfür die Query aus?

    Besten Dank
    xrax
     

  2. #2
    CPoly CPoly ist offline Mitglied Weizenbier
    tutorials.de Premium-User
    Registriert seit
    Sep 2009
    Beiträge
    2.445
    Bevor wir mit Lösungsansätzen anfangen, muss ich nochmal Klarheit schaffen. Müsste das Ergebnis nach deiner Erklärung nicht folgendes sein?
    Nr name
    1 ABC
    3 GHI

    Denn vor 3|ABC steht ja 2|DEF

    Du möchtest keine Ergebnisse, die an ein "DEF" grenzen?

    Edit:
    Und noch was:
    Haben die Spalten auch einen Primärschlüssel den man zu Rate ziehen kann?
    Geändert von CPoly (26.07.10 um 23:59 Uhr)
     

  3. #3
    Avatar von Yaslaw
    Yaslaw Yaslaw ist offline n/a
    tutorials.de Moderator
    Registriert seit
    Dec 2007
    Ort
    Winterthur(CH)
    Beiträge
    5.205
    Auf die schnelle und ungetestet
    Code sql:
    1
    2
    3
    4
    5
    6
    7
    8
    
    SELECT
        nr, name
    FROM
        mytable
    WHERE nr NOT IN (
            SELECT DISTINCT nr 
            FROM mytable 
            WHERE name = 'DEF')
    Du solltest einen Index auf nr haben. Ev auch einen auf nr & name
     
    ---------------------------------------------------------------------------------------------------
    item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen (Auch SQL-Statements kann man formatieren!)
    item: Tutorial: [PHP][MySQL] Debug Queries
    item: Schreibt mir keine PN mit Fragen die im Forum beantwortet werden können - ich mache kein persönliches coaching
    item: Bitte zur besseren Lesbarkeit PHP-Code in [PHP]...[/PHP], SQL in [SQL]...[/SQL], Visual Basic in [VB]...[/VB] etc. schreiben

  4. #4
    xrax xrax ist offline Mitglied Gold
    Registriert seit
    Oct 2004
    Beiträge
    133
    Danke CPoly,
    beim Ergebniss habe ich 4|ABC vergessen.
    Die Lösung von yaslaw macht was ich brauche...
     

  5. #5
    xrax xrax ist offline Mitglied Gold
    Registriert seit
    Oct 2004
    Beiträge
    133
    Besten Dank yaslaw,

    das wars was ich brauchte.

    Jetzt gehts an den Praxistest. Mal schauen wie lange die Abfragen dauern....

    Über nr und name ist der PK, drumm kann ich DISTINCT weglassen

    Gruß
    xrax
    Geändert von xrax (27.07.10 um 08:33 Uhr)
     

  6. #6
    Avatar von Yaslaw
    Yaslaw Yaslaw ist offline n/a
    tutorials.de Moderator
    Registriert seit
    Dec 2007
    Ort
    Winterthur(CH)
    Beiträge
    5.205
    Zitat Zitat von xrax Beitrag anzeigen
    Über nr und name ist der PK, drumm kann ich DISTINCT weglassen
    Solange du nur ein Name ausklammerst. Sind es aber mehrere Namen, kann die nr in der Unterabfrage wieder mehrfach vorkommen...
     
    ---------------------------------------------------------------------------------------------------
    item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen (Auch SQL-Statements kann man formatieren!)
    item: Tutorial: [PHP][MySQL] Debug Queries
    item: Schreibt mir keine PN mit Fragen die im Forum beantwortet werden können - ich mache kein persönliches coaching
    item: Bitte zur besseren Lesbarkeit PHP-Code in [PHP]...[/PHP], SQL in [SQL]...[/SQL], Visual Basic in [VB]...[/VB] etc. schreiben

  7. #7
    CPoly CPoly ist offline Mitglied Weizenbier
    tutorials.de Premium-User
    Registriert seit
    Sep 2009
    Beiträge
    2.445
    Jetzt versteh ich erst, was genau du meintest
    Aber yaslaw hats ja bereits gelöst.
     

  8. #8
    xrax xrax ist offline Mitglied Gold
    Registriert seit
    Oct 2004
    Beiträge
    133
    Ich habe das nochmals als Thema

    "Sätze mit gleichen Werten finden und andere Ausschliessen"

    geöffnet und dort erklärt was ich brauch.


    Hallo zusammen, hallo yaslaw

    mittlerweile läuft die Applikation und die Tabelle hat 600.000 Einträge.

    Zitat Zitat von yaslaw Beitrag anzeigen
    Auf die schnelle und ungetestet
    Code sql:
    1
    2
    3
    
    .....SELECT DISTINCT nr 
            FROM mytable 
            WHERE name = 'DEF')....
    Diese WHERE wird aber immer länger.

    Code :
    1
    
    [SQL]..WHERE name='DEF' OR name='AAA' OR name='ABC'.........

    Die Abfrage dauert bereits jetzt > 5 Sek. und die Tabelle wird auf mehrere Millionen wachsen.

    Ich hab jetzt was gebastelt, aber das Ergebnis stimmt leider nicht ganz. Dafür ist es viel schneller

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    SELECT tab1.nr, tab1.name
    FROM mytable AS tab1
    LEFT JOIN mytable AS tab2 ON tab2.nr = tab1.nr
    AND tab2.name 
    IN (
    'DEF', 'AAA', 'AXY'
    )
    WHERE tab1.name = 'ABC'
    AND tab2.nr IS NULL

    Das bringt mir nur die Datensätze von 'ABC' und nicht alle die gemeinsame nr mit ABC haben.

    Hat jemand hierzu eine Idee wie ich eine flotte Query hinbekomme?

    Besten Dank
    xrax
    Geändert von xrax (17.09.10 um 16:02 Uhr) Grund: blick bei meine erklärungen selbst nicht mehr durch
     

  9. #9
    Avatar von Steusi
    Steusi Steusi ist offline Nasenbär
    Registriert seit
    Sep 2006
    Ort
    MV
    Beiträge
    431
    Du könntest REGEXP nehmen, um deine bestimmten Einträge zu ermitteln.
    Noch einfacher ist es, wenn du eine eine kommaseparierte Liste ein SET darstellt.
    FIND_IN_SET() http://dev.mysql.com/doc/refman/5.1/...on_find-in-set
    Code sql:
    1
    
    WHERE FIND_IN_SET()
     
    Gruß Steusi

    Sollte dir ein Tipp von mir geholfen haben, freue ich mich auch über eine kleine Bewertung.
    Und wenn ein Problem gelöst ist, markiere deinen Beitrag bitte als erledigt.
    PHP-Code:
    $fehler "dummer Tippfehler";
    echo(
    "Und ist das Programm noch so klein, es passt immer noch ein ".$fehler". rein!"); 

  10. #10
    Avatar von Yaslaw
    Yaslaw Yaslaw ist offline n/a
    tutorials.de Moderator
    Registriert seit
    Dec 2007
    Ort
    Winterthur(CH)
    Beiträge
    5.205
    item: Die 2te Verknüpfung im ON-Teil des JOINS ist keine Verknüpfung sondern gehört in ein SQL
    item: Wozu hast du im WEHRE das folgende? Was soll das bewirken? tab1.name = 'ABC'

    Ich denke dass es etwa so aussehen könnte
    Code sql:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    SELECT 
        tab1.nr, 
        tab1.name
    FROM 
        mytable AS tab1
        LEFT JOIN (
                        SELECT nr 
                        FROM mytable 
                        WHERE name IN('DEF', 'AAA', 'AXY')
                     ) AS tab2 
            ON tab2.nr = tab1.nr
    WHERE
        tab2.nr IS NULL

    @Steusi
    Ich denke, FIN_IN_SET ist langsamer als IN(). Kann mich aber auch irren
     
    ---------------------------------------------------------------------------------------------------
    item: Ich habe es mir aus gesundheitlichen Gründen abgewöhnt unformatierten Code zu lesen (Auch SQL-Statements kann man formatieren!)
    item: Tutorial: [PHP][MySQL] Debug Queries
    item: Schreibt mir keine PN mit Fragen die im Forum beantwortet werden können - ich mache kein persönliches coaching
    item: Bitte zur besseren Lesbarkeit PHP-Code in [PHP]...[/PHP], SQL in [SQL]...[/SQL], Visual Basic in [VB]...[/VB] etc. schreiben

  11. #11
    gorefest gorefest ist offline Mitglied Brokat
    Registriert seit
    Apr 2009
    Beiträge
    256
    Yaslaws Vorschlag ist schon der richtige Weg,

    allerdings spannt Dir das IN eine Relation im Speicher / auf Platte auf, was extrem teuer ist.
    Versuch mal statt IN ein EXITSTS

    Code sql:
    1
    2
    3
    4
    5
    6
    7
    8
    
    SELECT
        nr, name
    FROM
        mytable A
    WHERE NOT EXISTS (
            SELECT 1 
            FROM mytable B
            WHERE B.name = 'DEF' AND A.NR = B.NR)

    Das sollte schneller gehen, insbesondere wenn name und nr indiziert sind.
     

Ähnliche Themen

  1. Antworten: 3
    Letzter Beitrag: 04.04.09, 13:26
  2. Sehr großer MySQL-Batch
    Von HerHde im Forum Linux & Unix
    Antworten: 4
    Letzter Beitrag: 27.12.08, 05:08
  3. SELECT ergebniss von Tabelle 1 in Tabelle 2 schreiben MySql
    Von Silver83 im Forum Relationale Datenbanksysteme
    Antworten: 5
    Letzter Beitrag: 23.03.08, 00:04
  4. MySQL - Kunden aus Tabelle die keinen Eintrag in Tabelle Bank haben
    Von Hubivan im Forum Relationale Datenbanksysteme
    Antworten: 2
    Letzter Beitrag: 09.07.07, 12:25
  5. Antworten: 1
    Letzter Beitrag: 05.05.07, 19:44