[SQL] Where-Abfrage über mehrere Tabellen

M3Y3R

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

ich habe folgende Abfrage:
SELECT
obj1.name1 AS "Display Name",
svc.display_name AS "Alias",
nagios_servicestatus.current_state AS "Status",
nagios_servicestatus.output AS "Output"

FROM

nagios_servicestatus

INNER JOIN nagios_objects AS obj1 ON (nagios_servicestatus.service_object_id = obj1.object_id)
INNER JOIN nagios_services AS svc ON (nagios_servicestatus.service_object_id = svc.service_object_id)

WHERE nagios_servicestatus.problem_has_been_acknowledged='0' AND nagios_servicestatus.current_state != '0'

ORDER BY "Display Name" ASC, "Alias" ASC;

Das erzeugt auch meine gewünchte Ausgabe. Nur wird mir alles doppelt angezeigt, da dies auch doppelt in der Datenbank drin steht. Wie kann ich nun die WHERE-Abfrage erweiteren, dass er nach nagios_objects.objecttype_id='1' sucht?

Danke für die Hilfe!


Mit freundlichen Grüßen
Papenburger
 
Hi,

1) Zahlen sind keine Strings
2) Redundanz zeugt in der Regel von schlechtem Datenbankdesign (Tobi: Ja, man kann Redundanz auch bewusst sinnvoll einsetzen => Performance ;))
3) Einfach die Bedingung in den WHERE Part reinschreiben oder den ON-Teil des Joins verändern

Johnson
 
Die Datenbank ist der Performance halber.
Das mit "in die Where-Clausel packen" funktionierte auch nicht, deswegen hab ich hier ja auch geschrieben.
 
2) Redundanz zeugt in der Regel von schlechtem Datenbankdesign (Tobi: Ja, man kann Redundanz auch bewusst sinnvoll einsetzen => Performance ;))
:LOL:
wie du an mich denkst :LOL:


Wow, was ist denn das für eine Applikation, dass die Performance so wichtig ist? Bei sevenload versteh ich das ja, aber so - naja ...
Ist bei jeder Anwendung nicht die Performance wichtig? Die Hessische "Schüler und Lehrer Datenbank" (LUSD) ist auch kein sevenload, haben ja nur "nen paar schulen" in Hessen Zugriff um Ihre Daten zu managen, und da wurde auch nicht auf Performance geachtet. Ergebniss? Die Eingabemasken brauchen 5min zum Aufbauen und das Eintragen eines neuen Schülers in das System dauert wegen dem ganzen Mist 30min. :LOL:
Preis: 20mio € für den Mist^^

Nebenbei hat ne Google-Studie mal ergeben, dass ein Seitenaufbau der länger als 0.4sec, also das 0.4 noch nichts begonnen wird, im Hinterkopf den Besucher zum wegsurfen bewegen.
 
:LOL:
wie du an mich denkst :LOL:

Ich kann halt hellsehen ;)


Ist bei jeder Anwendung nicht die Performance wichtig? Die Hessische "Schüler und Lehrer Datenbank" (LUSD) ist auch kein sevenload, haben ja nur "nen paar schulen" in Hessen Zugriff um Ihre Daten zu managen, und da wurde auch nicht auf Performance geachtet. Ergebniss? Die Eingabemasken brauchen 5min zum Aufbauen und das Eintragen eines neuen Schülers in das System dauert wegen dem ganzen Mist 30min. :LOL:
Preis: 20mio € für den Mist^^

Ob wirklich das Einhalten bestimmter Normalformen der Grund dafür ist?
Ich persönlich bin der Ansicht, dass Normalformen nicht umsonst Normalformen heißen und man sie nur verletzen sollte, wenn es performancetechnisch unbedingt notwendig ist - der Mehraufwand an Programmierarbeit bei Redundanz (abgesehen von Fehlern, die bei sich bei redundanten Daten um einiges leichter einschleichen) und die Unübersichtlichkeit finde ich daher nicht immer vertretbar. :p
 
Was wird doppelt angezeigt? Schau dir einfachmal GROUP BY oder DISTINCT an...

Wow, was ist denn das für eine Applikation, dass die Performance so wichtig ist? Bei sevenload versteh ich das ja, aber so - naja ...[...]
Ob wirklich das Einhalten bestimmter Normalformen der Grund dafür ist?
Ich persönlich bin der Ansicht, dass Normalformen nicht umsonst Normalformen heißen und man sie nur verletzen sollte, wenn es performancetechnisch unbedingt notwendig ist - der Mehraufwand an Programmierarbeit bei Redundanz (abgesehen von Fehlern, die bei sich bei redundanten Daten um einiges leichter einschleichen) und die Unübersichtlichkeit finde ich daher nicht immer vertretbar.

Schon mal irgendwie praktisch mit SQL gearbeitet? Es gibt Queries die gehen ein wenig über "SELECT * FROM foo" drüberraus. Und wie das ebend mal so mit Theorie und Praxis so ist, kann man die Normalformen nicht 1:1 übertragen. Es fängt bei einer simplen Adresse an... wann ist eine Adresse atomar und erfüllt die erste Normalform? Oder warum gibt es in Mysql ein Datentyp Names enum oder set? Das erste verstößt gegen die 2ten Normalform, der zweite verstößt sogar gegen die 1te und die 2te. Und warum? Ganz einfach weil eine normalisierung in keinen verhältnis stände. Oder wie schauts bei diesem Problem aus:

Ich habe einen Datensatz und zu diesem Datensatz möchte ich den Status und das Datum des Status protokollieren. Sprich ich habe Tabelle 1 mit den Datensätzen und eine 2te Tabelle mit dem Statusprotokoll. Wie bekomm ich jetzt meine Daten wenn ich das ganze in Normalform lasse? Schon das Auslesen eines einzelnen Datensatzes macht so Probleme, gechweigeden wenn man mehrere auslesen will. Also was macht man? Man denormalisiert das ganze und speichert den Status und das Datum zusätzlich in der Tabelle Datensätze. (Natürlich würde es auch in der Normalform gehen, aber mit Mysql wäre dass ein performance killer... mit Oracle oder Mssql könnte man drüber reden)

Und es gibt bei weitem mehr solche konstelationen in der Praxis. Denormalisierung hat sein sinn und sollte auch gezielt eingesetzt werden. Wer nicht sinnvoll denormalisieren kann der wird irgendwann mal Probleme bekommen.

PS: manche Leute denormalisieren auch ohne es zuwissen schon alleine... :roll:
 
PHP:
SELECT
obj1.name1 AS "Display Name",
svc.display_name AS "Alias",
nagios_servicestatus.current_state AS "Status",
nagios_servicestatus.output AS "Output"

FROM

nagios_servicestatus

INNER JOIN nagios_objects AS obj1 ON (nagios_servicestatus.service_object_id = obj1.object_id)
INNER JOIN nagios_services AS svc ON (nagios_servicestatus.service_object_id = svc.service_object_id)

WHERE nagios_servicestatus.problem_has_been_acknowledged='0' AND nagios_servicestatus.current_state != '0'

ORDER BY "Display Name" ASC, "Alias" ASC;
[...]
Wie kann ich nun die WHERE-Abfrage erweiteren, dass er nach nagios_objects.objecttype_id='1' sucht?

Mal abgesehen von der Diskussion über das Datenbank-Design:
Wo ist das Problem? Klausel einfügen und gut...

PHP:
SELECT      obj1.name1                          AS  "Display Name"
          , svc.display_name                    AS  "Alias"
          , nagios_servicestatus.current_state  AS  "Status"
          , nagios_servicestatus.output         AS  "Output"
FROM        nagios_servicestatus
INNER JOIN  nagios_objects  AS obj1
  ON        obj1.object_id                                      = nagios_servicestatus.service_object_id
  AND       obj1.objecttype_id                                  = '1'
INNER JOIN  nagios_services AS svc
  ON        svc.service_object_id                               = nagios_servicestatus.service_object_id
WHERE       nagios_servicestatus.problem_has_been_acknowledged  =   '0'
  AND       nagios_servicestatus.current_state                  !=  '0'
ORDER BY    "Display Name"  ASC
          , "Alias"         ASC

Das mit "in die Where-Clausel packen" funktionierte auch nicht, deswegen hab ich hier ja auch geschrieben.
Was heißt denn "funktionierte auch nicht"? Gab einen Fehler, oder lieferte die Daten immer noch doppelt, oder wie?
 
[...]Und wie das ebend mal so mit Theorie und Praxis so ist, kann man die Normalformen nicht 1:1 übertragen.[...]

Hab mich gestern nochmal mit Ice darüber unterhalten und bin überzeugt, dass es alles andere als sinnvoll ist sämtliche Normalformen einzuhalten.
Allerdings werde ich, wann immer möglich, versuchen so viele Normalformen wie sinnvoll möglich einzuhalten.

Aber auch ich würde nie auf die Idee kommen ein Feld 'adresse' auszulagern, weil es in vielen Fällen doch unique ist (auch wenn das nicht der Theorie entspricht) - sogesehen denormalisiere ich auch ;)

War vielleicht auch etwas missverständlich formuliert und vorallem der letzte Satz stand auch im Wiederspruch zu meiner Aussage weiter oben ... insofern nochmal danke für die Aufklärung :)
 
Keine Ahnung, ob das Problem immer noch besteht, aber hier mal mein Vorschlag:

SELECT DISTINCT
obj1.name1 AS "Display Name",
svc.display_name AS "Alias",
nagios_servicestatus.current_state AS "Status",
nagios_servicestatus.output AS "Output"
FROM
nagios_servicestatus
INNER JOIN nagios_objects AS obj1
ON (nagios_servicestatus.service_object_id = obj1.object_id)
INNER JOIN nagios_services AS svc
ON (nagios_servicestatus.service_object_id = svc.service_object_id)
WHERE nagios_servicestatus.problem_has_been_acknowledged=0
AND nagios_servicestatus.current_state != 0
AND nagios_objects.objecttype_id=1
ORDER BY 1,2;