Abfrage über n Tabellen

Randy Busher

Benutzer
Beiträge
10
Hallo ihr :)
Vielen Dank, dass Du Dir meine Frage anschaust.

Um die Fragestellung zu vereinfachen, habe ich ein SQL DUMP welches so ausschaut:

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';

CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET utf8 ;
USE `mydb` ;


CREATE TABLE IF NOT EXISTS `mydb`.`DasHaus` (
`idDasHaus` INT NOT NULL AUTO_INCREMENT,
`Bauform` VARCHAR(45) NULL,
PRIMARY KEY (`idDasHaus`))
ENGINE = InnoDB;


CREATE TABLE IF NOT EXISTS `mydb`.`EinrichtungSitze` (
`idEinrichtungSitze` INT NOT NULL AUTO_INCREMENT,
`Sitzgelegenheit` VARCHAR(45) NULL,
PRIMARY KEY (`idEinrichtungSitze`))
ENGINE = InnoDB;


CREATE TABLE IF NOT EXISTS `mydb`.`EinrichtungSitze_has_DasHaus` (
`EinrichtungSitze_idEinrichtungSitze` INT NOT NULL,
`DasHaus_idDasHaus` INT NOT NULL,
PRIMARY KEY (`EinrichtungSitze_idEinrichtungSitze`, `DasHaus_idDasHaus`),
INDEX `fk_EinrichtungSitze_has_DasHaus_DasHaus1_idx` (`DasHaus_idDasHaus` ASC) VISIBLE,
INDEX `fk_EinrichtungSitze_has_DasHaus_EinrichtungSitze_idx` (`EinrichtungSitze_idEinrichtungSitze` ASC) VISIBLE,
CONSTRAINT `fk_EinrichtungSitze_has_DasHaus_EinrichtungSitze`
FOREIGN KEY (`EinrichtungSitze_idEinrichtungSitze`)
REFERENCES `mydb`.`EinrichtungSitze` (`idEinrichtungSitze`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_EinrichtungSitze_has_DasHaus_DasHaus1`
FOREIGN KEY (`DasHaus_idDasHaus`)
REFERENCES `mydb`.`DasHaus` (`idDasHaus`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;


CREATE TABLE IF NOT EXISTS `mydb`.`Bodenbelag` (
`idDachziegel` INT NOT NULL AUTO_INCREMENT,
`Bodenbelag` VARCHAR(45) NULL,
PRIMARY KEY (`idDachziegel`))
ENGINE = InnoDB;


CREATE TABLE IF NOT EXISTS `mydb`.`Bodenbelag_has_DasHaus` (
`Bodenbelag_idDachziegel` INT NOT NULL,
`DasHaus_idDasHaus` INT NOT NULL,
PRIMARY KEY (`Bodenbelag_idDachziegel`, `DasHaus_idDasHaus`),
INDEX `fk_Bodenbelag_has_DasHaus_DasHaus1_idx` (`DasHaus_idDasHaus` ASC) VISIBLE,
INDEX `fk_Bodenbelag_has_DasHaus_Bodenbelag1_idx` (`Bodenbelag_idDachziegel` ASC) VISIBLE,
CONSTRAINT `fk_Bodenbelag_has_DasHaus_Bodenbelag1`
FOREIGN KEY (`Bodenbelag_idDachziegel`)
REFERENCES `mydb`.`Bodenbelag` (`idDachziegel`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Bodenbelag_has_DasHaus_DasHaus1`
FOREIGN KEY (`DasHaus_idDasHaus`)
REFERENCES `mydb`.`DasHaus` (`idDasHaus`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;


CREATE TABLE IF NOT EXISTS `mydb`.`Treppenart` (
`idTreppenart` INT NOT NULL AUTO_INCREMENT,
`Treppenbelag` VARCHAR(45) NULL,
PRIMARY KEY (`idTreppenart`))
ENGINE = InnoDB;


CREATE TABLE IF NOT EXISTS `mydb`.`Treppenart_has_DasHaus` (
`Treppenart_idTreppenart` INT NOT NULL,
`DasHaus_idDasHaus` INT NOT NULL,
PRIMARY KEY (`Treppenart_idTreppenart`, `DasHaus_idDasHaus`),
INDEX `fk_Treppenart_has_DasHaus_DasHaus1_idx` (`DasHaus_idDasHaus` ASC) VISIBLE,
INDEX `fk_Treppenart_has_DasHaus_Treppenart1_idx` (`Treppenart_idTreppenart` ASC) VISIBLE,
CONSTRAINT `fk_Treppenart_has_DasHaus_Treppenart1`
FOREIGN KEY (`Treppenart_idTreppenart`)
REFERENCES `mydb`.`Treppenart` (`idTreppenart`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Treppenart_has_DasHaus_DasHaus1`
FOREIGN KEY (`DasHaus_idDasHaus`)
REFERENCES `mydb`.`DasHaus` (`idDasHaus`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;


SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;



------------------------------SCHNIPP HIER -------------------

Ich habe nun folgendes Problem, ich habe 170 Häuser in der Tabelle: Das Haus und einige von denen sind auch schon mit Treppen und Bodenbelag und Sitzen eingerichtet, aber nicht alle.
Wie sieht die Abfrage aus, wenn ich ausschließlich die Häuser angezeigt haben möchte, die weder Bodenbelag, noch Treppe noch Sitze haben. Also die, die noch im "Rohbau" sind.
Ich suche auch gern woanders, wenn ich denn wüsste, wonach ich eigentlich suche. :) Join Left, Inner Join etc passt irgendwie nicht so richtig, da die DB nur exemplatisch ist und es im Produktivsytem 12 weitere n:m Verknüpfungen gibt.

Vielen Dank, dass Du bis hier gelesen hast. Wenn Dein Impuls jetzt ist, mir zu antworten: Na ja, mein Onkel hatte auch mal eine Garage o.ä. dann wäre es nett, wenn Du das nicht machen würdest. :)

LG Randy
 
Werbung:
Dann habe ich also:

Select DH.idHaus
FROM DasHaus DH
LEFT JOIN [Tabelle1] ON DH.idHaus = [Tabelle1].idHaus
LEFT JOIN [Tabelle2] ON DH.idHaus = [Tabelle2].idHaus
LEFT JOIN [Tabelle3] ON DH.idHaus = [Tabelle3].idHaus
LEFT JOIN [Tabelle4] ON DH.idHaus = [Tabelle4].idHaus
LEFT JOIN [Tabelle5] ON DH.idHaus = [Tabelle5].idHaus
LEFT JOIN [Tabelle6] ON DH.idHaus = [Tabelle6].idHaus
LEFT JOIN [Tabelle7] ON DH.idHaus = [Tabelle7].idHaus
LEFT JOIN [Tabelle8] ON DH.idHaus = [Tabelle8].idHaus
LEFT JOIN [Tabelle9] ON DH.idHaus = [Tabelle9].idHaus
LEFT JOIN [Tabelle10] ON DH.idHaus = [Tabelle10].idHaus
LEFT JOIN [Tabelle11] ON DH.idHaus = [Tabelle11].idHaus
LEFT JOIN [Tabelle12] ON DH.idHaus = [Tabelle12].idHaus



WHERE DH.idHaus <> NULL; ??
 
Wie kommst Du von Deinem Dump und den dort gezeigten Tabellen auf die Tabellen in deinem SQL Versuch?
Was soll tabelle1 -12 sein?

Eine Null Prüfung wird in SQL so ausgedrückt:
[where] <Ausdruck> is not null
oder expliziter
where <Spaltenname> is not null
oder in Deinem Fall
DasHaus_idDasHaus is not null

Die Null Prüfung erfolgt dabei nicht auf Seite der Haupttabelle, also nicht die linke (left).
Die Prüfung erfolgt auf der anderen Seite, die Seite/Tabelle wo Werte vorhanden sein können oder halt nicht.
Prüft man dort auf NULL, so erhält man alle Datensätze bei denen der Join nicht erfüllt ist, prüft man auf not null, so erhält man alle Datensätz wo der Join erfüllt ist. Dieser Fall entspricht einem normalen (nicht outer) Join.
 
Wie kommst Du von Deinem Dump und den dort gezeigten Tabellen auf die Tabellen in deinem SQL Versuch?
Was soll tabelle1 -12 sein?
Wie ich erwähnte, habe ich 12 weitere n:m Beziehungen, die in dieser Abfrage eine Rolle spielen.
Die [] (eckige Klammer) ist dann ein Ausdruck für eine Syntax. So hatte ich es zumindest geplant. [Tabelle1] heißt im Produktivsystem dann tbl_hausanschluss z.B.
Einen kompletten Dump von der gesamten DB zu liefern wäre dann aber doch über das Ziel hinausgeschossen, deshalb gab es nur einen Auszug.

Eine Null Prüfung wird in SQL so ausgedrückt:
[where] <Ausdruck> is not null
oder expliziter
where <Spaltenname> is not null
oder in Deinem Fall
DasHaus_idDasHaus is not null
IS NOT NULL verstehe ich und würde ich auch gern machen, allerdings komme ich mit der eigentlichen SQL Anweisung nicht hin.
Der Hinweis, nach LEFT JOIN zu suchen hilft mir aber schon mal. Nun kann ich ganz bequem woanders suchen und hoffentlich mein Problem lösen.
Dafür also vielen Dank :)
Die Null Prüfung erfolgt dabei nicht auf Seite der Haupttabelle, also nicht die linke (left).
Die Prüfung erfolgt auf der anderen Seite, die Seite/Tabelle wo Werte vorhanden sein können oder halt nicht.
Prüft man dort auf NULL, so erhält man alle Datensätze bei denen der Join nicht erfüllt ist, prüft man auf not null, so erhält man alle Datensätz wo der Join erfüllt ist. Dieser Fall entspricht einem normalen (nicht outer) Join.

Ja, damit komme ich ja genau nicht ans Ziel, wo ich hin will.
So bekomme ich heraus, ob ein Haus schon einen Bodenbelag hat, oder nicht. Die ursprüngliche Frage dreht sich allerdings um die Frage, welches Haus noch gar keine Ausstattungsmerkmale bekommen hat, also nicht nur Bodenbelag, sondern auch Anschlüsse, Garage, Dach, Türen, Sitze etc.
 
Hast Du schon mal eine left join Abfrage ausgeführt? Mit Daten, die teilweise den Join erfüllt haben und teilweise nicht?
Man sieht wunderbar, wie die Haupttabelle (links) ihre Daten liefert und die Nebentabelle (rechts) Lücken in den Daten aufweist.

is not null ist natürlich in Deinem Fall Blödsinn. Ich weiß nicht, wie ich darauf gekommen bin. Vielleicht weil Du selbst oben "<> Null" geschrieben hast. Du willst die Datensätze haben, wo die Nebentabelle keine Daten liefert und zwar überall (alle 12)

also muss es überall heißen, für jeden join:
tabelle1.fkdasHausColumn is null
and
tabelle2.fkdasHausColumn is null
usw.
 
Werbung:
Zurück
Oben