MySQL Abfrage mit mehreren Tabellen



  • Hallo!

    Ich habe 3 Tabellen Deck, Card und CardInDeck die folgendermaßen strukturiert sind:
    Card: ID, OwnerID, CardName
    CardInDeck: CardID, DeckID
    Deck: ID, OwnerID, DeckName

    Ich habe nun OwnerID=1 und DeckName="My very first Deck" gegeben und möchte alle CardIDs haben die zum DeckID passen.

    Das Schachteln habe ich nicht hinbekommen.
    Bin auf diese Lösung gekommen:
    SELECT CardID FROM CardInDeck WHERE DeckID = (SELECT ID FROM Deck WHERE OwnerID=1 AND DeckName="My very first Deck" LIMIT 1)

    Wenn ich nun auch CardName haben möchte müsste ich noch einmal schachteln?
    Geht es auch einfacher?
    Bin nicht so bewandert im Umgang mit MySQL-Querys und bin für Tipps und Hinweise auf Problematiken dankbar!

    Danke!



  • Hi!

    Du suchst wahrscheinlich JOINs:

    SELECT
    	c.CardID
    	, c.CardName
    FROM
    	Deck d
    	INNER JOIN CardInDeck cid ON d.DeckID = cid.DeckID
    	INNER JOIN Card c ON cid.CardID = c.CardID
    WHERE
    	d.DeckName = 'My very first Deck'
    

    Aber eine Frage hab ich zu deiner Tabellenstruktur? Wozu hat Card eine OwnerID? Der Owner einer Karte sollte sich doch durch das Deck ergeben, das ja wiederum selbst eine OwnerID hat.



  • Danke für die schnelle Antwort.

    Zu deiner Frage: eine Karte muss ja nicht zwingend in einem Deck sein, sie kann ja auch nur in einer Collection sein und wird in keinem Deck verwendet. Das war mein Gedanke zu der Struktur.

    Versuche jetzt mit JOINs die Kartennamen zu bekommen.



  • Ich würde folgendes empfehlen:

    SELECT * FROM Card c
    WHERE c.ID IN (
        SELECT cd.CardID FROM CardInDeck cd
        WHERE cd.DeckID IN (
            SELECT d.ID FROM Deck d
            WHERE d.OwnerID = 1 AND d.DeckName = "My very first Deck"
        )
    )
    

    Das bildet mMn. besser die Semantik "zeig mir alle Karten die von Deck X verwendet werden" ab. Also mal davon ausgehend dass das die Frage ist die du von der Abfrage beantwortet haben möchtest.

    Und falls die WHERE Bedingung mal für 2 oder mehr Decks gilt, bekommst du damit keine Duplikate. Also falls die selbe Karte in mehreren Decks vorkommt. Bei der Variante von Zusammenführer würdest du so einem Fall Duplikate bekommen.

    @Zusammenführer
    Es wird wohl Karten geben die in keinem Deck drinnen sind.
    Und wenn es auch leere Decks geben kann, dann brauchen sowohl Card als auch Deck jeweils einen Owner.
    Bzw. vielleicht soll es ja sogar erlaubt sein dass man in seinem Deck Karten eines Freundes verwendet.



  • hustbaer schrieb:

    Ich würde folgendes empfehlen:

    ...
    

    Das bildet mMn. besser die Semantik "zeig mir alle Karten die von Deck X verwendet werden" ab. Also mal davon ausgehend dass das die Frage ist die du von der Abfrage beantwortet haben möchtest.

    Guter Einwand, hustbaer! Könnte man das sogar noch mit zwei EXISTS verbessern?

    Vielleicht so:

    SELECT
    	*
    FROM
    	Card c
    WHERE
    	EXISTS
    	(
    		SELECT
    			*
    		FROM
    			CardInDeck cd
    		WHERE
    			cd.CardID = c.ID
    			AND EXISTS
    			(
    				SELECT
    					*
    				FROM
    					Deck d
    				WHERE
    					cd.DeckID = d.ID
    					AND d.OwnerID = 1
    					AND d.DeckName = 'My very first Deck'
    			)
    	)
    

    Hab das auch schnell hingeschnöselt und nicht getestet 🙂

    Jetz weiß ich aber nicht, ob es in MySQL EXISTS gibt, da ich fast ausschließlich mit MS SQL Server arbeite.

    hustbaer schrieb:

    Und falls die WHERE Bedingung mal für 2 oder mehr Decks gilt, bekommst du damit keine Duplikate. Also falls die selbe Karte in mehreren Decks vorkommt. Bei der Variante von Zusammenführer würdest du so einem Fall Duplikate bekommen.

    Stimmt, da hatte ich zu voreilig was hingezimmert.

    hustbaer schrieb:

    @Zusammenführer
    Es wird wohl Karten geben die in keinem Deck drinnen sind.
    Und wenn es auch leere Decks geben kann, dann brauchen sowohl Card als auch Deck jeweils einen Owner.
    Bzw. vielleicht soll es ja sogar erlaubt sein dass man in seinem Deck Karten eines Freundes verwendet.

    Macht Sinn!

    @hustbaer: Wieso verwendest du eigentlich doppelte Anführungszeichen anstatt einfacher?



  • Zugeber schrieb:

    @hustbaer: Wieso verwendest du eigentlich doppelte Anführungszeichen anstatt einfacher?

    Hab den Code des OP Copy & Paste übernommen und dann umgebaut. Dabei sind die "" des OP übriggeblieben.
    "" für String Literals ist in SQL Quatsch, da haste natürlich Recht.


Anmelden zum Antworten