[MySQL] Statement funktioniert nicht

M3Y3R

Well-known member
ID: 336361
L
8 Mai 2006
1.608
60
Hallo,

ich habe zwei Tabellen (logs und logs_blacklist). Darin sind folgende Einträge enthalten:

Tabelle: logs_blacklist / Spalte: message
dhcp\[[[:alpha:]]+\][[:blank:]]+1002
tcpip\[[[:alpha:]]+\][[:blank:]]+[[:digit:]]

Tabelle logs / Spalte: msg
security[success] 538 DELL\Administrator Benutzerabmeldung: Benutzername:Administrator Domäne: DELL Anmeldekennung: (0x0,0xA40BD4) Anmeldetyp:2

security[success] 538 DELL\Administrator Benutzerabmeldung: Benutzername:Administrator Domäne: DELL Anmeldekennung: (0x0,0xA40BD4) Anmeldetyp:2

uvm.

Nun versuche ich über folgendes Statement alle mit dem entsprechendem Pattern aus der logs_blacklist auszublenden:
PHP:
SELECT * FROM logs AS l INNER JOIN logs_blacklist AS lb WHERE l.msg NOT REGEXP lb.message AND ((lb.global = 1) OR(lb.global = 0 AND l.host = lb.hostaddress)) ORDER BY datetime DESC LIMIT 0, 25

Es werden aber weder die Enträge ausgeblendet noch wird nachgeschaut ob die Einträge für einen oder Alle Hosts ausgeblendet werden soll.

Worin besteht mein Fehler und wer kann mir helfen?


MFG
Papenburger
 
mit dem INNER JOIN verknüpfst Du erst mal jede Zeile der ersten Tabelle mit jeder Zeile der zweiten Tabelle. Und dann erst wird für jede Kombination(!) separat(!) geprüft, ob die WHERE-Bedingung passt oder nicht.

Ich glaube nicht, dass es das ist, was Du eigentlich willst.

Ich vermute mal, Du willst eher so etwas.

SELECT daten FROM logs l
WHERE NOT EXISTS
( SELECT * FROM logs_blacklist lb
WHERE l.msg REGEXP lb.message AND (lb.global = 1 OR (lb.global = 0 AND l.host = lb.hostaddress) ))

bei diesem SELECT wird jede Zeile der logs einmal gegen alle blacklist-Einträge geprüft und nur ausgegeben, wenn kein einziger Eintrag zutrifft
 
Genau so hatte ich mir das gedacht...
Danke! Eigentlich recht simple aber meiner einer bekommt das nicht hin :oops:

MFG
Papenburger
 
SELECT * FROM logs l
WHERE NOT EXISTS
( SELECT * FROM logs_blacklist lb
WHERE l.msg REGEXP lb.message AND (lb.global = 1 OR (lb.global = 0 AND l.host = lb.hostaddress) ))
Leider bekomme ich über den oben genannten Statement keine ID´s der Blacklist mitgeliefert.

Wenn ich das anders schreibe, erhalte ich zwar die ID´s aber die Einträge vervielfachen sich!
SELECT logs_blacklist.*, logs.* FROM logs l, logs_blacklist lb
WHERE NOT EXISTS
( SELECT * FROM logs_blacklist lb
WHERE l.msg REGEXP lb.message AND (lb.global = 1 OR (lb.global = 0 AND l.host = lb.hostaddress) ))

Wer kann mir weiter helfen?
 
Das ursprüngliche SELECT liefert Dir alle Sätze zurück, für die *kein* Blacklist-Eintrag existiert, welche Blacklist-ID willst Du da mit zurückbekommen ?
 
...welche Blacklist-ID willst Du da mit zurückbekommen ?

In der logs_blacklist ist ein Primery Key, wie auch in der logs.
Ich möchte nun den PrimeryKey von der logs_blacklist haben...

Wie schon gesagt, beim zweiten Statement vervielfachen sich die Einträge was nicht sein darf...

Müsste so wie beim ersten Statement sein, nur dass das ID-Feld der logs_blacklist mit ausgegeben wird...
 
sorry, jetzt steh ich völlig auf dem Schlauch. Jetzt brauch ich mal ein Beispiel.

Angenommen, die Tabelleninhalte schauen so aus:

logs:
ID msg
== ----
01 ich bin eine Zeile, die pattern-1 entspricht
02 ich bin eine Zeile, die keinen pattern entspricht
03 ich bin eine Zeile, die pattern-2 entspricht
04 ich bin eine Zeile, die ebenfalls pattern-2 entspricht

logs_blacklist:
ID pattern
== --------
01 pattern-1
02 pattern-2
03 pattern-3


( das mit dem global bzw. hostadress lass ich jetzt der Einfachheit halber weg )
was soll dann die genaue Ergebnismenge sein ?
 
ich würde mal sagen alles von logs + id von logs_blacklist

das ist zu unpräzise. Was ist "alles von logs" ?
Alle Zeilen ? alle Zeilen, die einem pattern entsprechen ? oder alle Zeilen die keinem pattern entsprechen ?
Und welche id von logs_blacklist ?
Jede Zeile mit jeder verknüpft ? immer nur wenn ein pattern übereinstimmt ? immer, wenn ein pattern nicht übereinstimmt ? ...
 
das ist zu unpräzise. Was ist "alles von logs" ?
Alle Zeilen ? alle Zeilen, die einem pattern entsprechen ? oder alle Zeilen die keinem pattern entsprechen ?
Und welche id von logs_blacklist ?
Jede Zeile mit jeder verknüpft ? immer nur wenn ein pattern übereinstimmt ? immer, wenn ein pattern nicht übereinstimmt ? ...

SELECT * FROM logs l
WHERE NOT EXISTS
( SELECT * FROM logs_blacklist lb
WHERE l.msg REGEXP lb.message AND (lb.global = 1 OR (lb.global = 0 AND l.host = lb.hostaddress) ))
Das Statement gibt alle Einträge (Zeilen & Spalten) aus auf dem die Ausdrücke der logs_blacklist nicht zutreffen (NOT EXISTS). Nun brauche ich aber noch das ID-Feld der logs_blacklist...

Also wäre das eine Ausgabe der logs, wenn ein Pattern nicht übereinstimmt.
Hinzu soll die ID des logs_blacklist.
 
Hinzu soll die ID des logs_blacklist.


Du hast viele IDs in der logs_blacklist.
Welche dieser IDs willst Du denn in der Zeile zusätzlich haben ?

In meinem Beispiel hättest Du als Ergebnismenge bisher:

logsID logs.message ................................... blacklistID
-------------------------------------------------------------------
02 ....ich bin eine Zeile, die keinen pattern entspricht ...???



Welche blacklistID willst Du denn hier haben, ich habe ( in meinem Beispiel ) die Nummern 01, 02 und 03 zur Auswahl



oder willst Du eine Ausgabe, die dem entspricht:

logsID logs.message ................................... blacklistID
-------------------------------------------------------------------
01 ....ich bin eine Zeile, die pattern-1 entspricht ........... 02
01 ....ich bin eine Zeile, die pattern-1 entspricht ........... 03
02 ....ich bin eine Zeile, die keinen pattern entspricht ...... 01
02 ....ich bin eine Zeile, die keinen pattern entspricht ...... 02
02 ....ich bin eine Zeile, die keinen pattern entspricht ...... 03
03 ....ich bin eine Zeile, die pattern-2 entspricht ........... 01
03.... ich bin eine Zeile, die pattern-2 entspricht ........... 03
04 ....ich bin eine Zeile, die ebenfalls pattern-2 entspricht.. 01
04.... ich bin eine Zeile, die ebenfalls pattern-2 entspricht.. 03

 
Zuletzt bearbeitet:
logsID logs.message ................................... blacklistID
-------------------------------------------------------------------

02 ....ich bin eine Zeile, die keinen pattern entspricht ...... 01
02 ....ich bin eine Zeile, die keinen pattern entspricht ...... 02
02 ....ich bin eine Zeile, die keinen pattern entspricht ...... 03



Dies sind drei unterschiedliche Zeilen.
Wenn Du sagst, der Eintrag ( vermutlich meinst Du damit die logs.message ) soll nicht mehrfach ausgegeben werden, welche von diesen drei Zeilen soll dann konkret ausgegeben werden ?
Die mit der blacklistID 01, die mit der blacklistID 02 oder die mit der blacklistID 03 ?
 
Zuletzt bearbeitet:
Wieso verstehst du nicht was ich will?

Tabelle A / msg
IDl - msg
1 - Message 1
2 - Message 2
3 - Message 3

Tabelle B / message
IDlb - pattern
1 - [[:alpha:]][[:blank:]]2
2 - [[:alpha:]][[:blank:]]1

Ergebnis:
IDl - msg - IDlb
2 - Message 2 - 1
1 - Message 1 - 2
So in der art...

Wenn jetzt noch mehr Patterns vorhanden sind sollen die auch überprüft werden und entsprechend ausgegeben werden...


SO schwer ist das doch garnicht zu verstehen. Oben steht doch schon das Statement nur ohne der ID aus der blackliste, welche ich aber benötige!
 
Ich weiss grad nicht, ob ich's falsch verstehe, aber ich glaube, ihr redet aneinander vorbei. So wie es klingt, willst Du die Id des Patterns, das zu einem Eintrag passt, während Du oben davon sprichst, dass Du die Einträge willst, auf die kein Pattern passt (wozu es logischerweise keine eindeutige Id gibt).
 
@tleilax: danke, für Deinen Beitrag. Ich geh auch davon aus, dass ich die eigentliche Problemstellung noch nicht erfasst habe. Darum wollte ich ja auch das ganze an einem Beispiel gezeigt haben.
Ich habs die ganze Zeit so verstanden, dass Papenburger die msgs will, die keinem blacklist-Eintrag entsprechen.


@Papenburger:
Wenn Du wissen willst, welche Eintrage der logs *einem* pattern entsprechen, kannst Du Deine eigene query aus Beitrag #1 verwenden, und nur das NOT herauslassen.

SELECT * FROM logs AS l
INNER JOIN logs_blacklist AS lb
WHERE l.msg REGEXP lb.message
AND ((lb.global = 1) OR(lb.global = 0 AND l.host = lb.hostaddress))



wenn Du wissen willst, welcher Eintrag *keinem* pattern entspricht, kannst Du keine ID der blacklist dazufügen, weil es keine relevante gibt.
 
Okay.

Ich rufe das nun wie folgt auf:
PHP:
SELECT * FROM logs AS l
INNER JOIN logs_blacklist AS lb
WHERE l.msg REGEXP lb.message
AND ((lb.global = 1) OR(lb.global = 0 AND l.host = lb.hostaddress))

Wenn nur ein Pattern in der Blacklist steht wird alles richtig ausgegeben. Stehen aber zwei Pattern in der Blacklist, bekomme ich alle Einträge wieder ausgegeben, als ob keine Überprüfung stattgefunden hat.