[Solved] Inner join, outer join, union και τα μυαλά στα κάγκελα

Συζητήσεις για την βάση δεδομένων MySQL και το phpMyAdmin

Συντονιστές: WebDev Moderators, Super-Moderators

Απάντηση
Άβαταρ μέλους
eirinikp
Δημοσιεύσεις: 90
Εγγραφή: 04 Οκτ 2010 12:59

[Solved] Inner join, outer join, union και τα μυαλά στα κάγκελα

Δημοσίευση από eirinikp » 15 Ιούλ 2011 22:10

Γεια!
Χρησιμοποιώ τη mysql εμπειρικά, δεν έχω κάτσει ακόμα να μάθω όλη τη θεωρία, με αποτέλεσμα, να σκαλώνω σε λίγο πιο περίπλοκα ερωτήματα.
Υπόσχομαι να μελετήσω, όμως θα ήθελα να με βοηθήσετε σε ένα επείγον πρόβλημα:

Έστω ότι έχω τον table1:

Κώδικας: Επιλογή όλων

id             name       field3
input1       name1     something
input2       name2     something
input3       name3     mpla 
input4       name4     something
Και τον table2:

Κώδικας: Επιλογή όλων

id             table1_id       field4
id1           input1           somethingelse
id2           input4          gkouch
Θέλω ένα query, στο οποίο να παίρνω και τις καταχωρήσεις του table1 που δεν εμφανίζονται στον table2 αλλά και τις καταχωρήσεις που εμφανίζονται στον table2. Πρέπει να τα πάρω με ένα query μόνο.

To query που δοκίμασα (αλλά δε δουλεύει) είναι το εξής:

Κώδικας: Επιλογή όλων

SELECT t.id, t.name, t2.id
FROM table1 t
LEFT OUTER JOIN table2 t2 ON t.id = t2.table1_id
WHERE t.field3 = 'something'
AND t2.field4 = 'somethingelse'
Και τα επιθυμητά αποτελέσματα είναι τα εξής:

Κώδικας: Επιλογή όλων

input1     name1    id1
input2     name2    NULL
Ευχαριστώ πολύ!

Edit: "id2 name4 gkouch" => "id2 input4 gkouch"
Τελευταία επεξεργασία από το μέλος eirinikp την 18 Ιούλ 2011 21:55, έχει επεξεργασθεί 2 φορές συνολικά.


Άβαταρ μέλους
eirinikp
Δημοσιεύσεις: 90
Εγγραφή: 04 Οκτ 2010 12:59

[Solved] Inner join, outer join, union και τα μυαλά στα κάγκελα

Δημοσίευση από eirinikp » 16 Ιούλ 2011 11:26

Μα από αυτό το link, εγώ καταλαβαίνω ότι χρειάζομαι το LEFT OUTER JOIN, το οποίο και έβαλα. Δυστυχώς το output που μου δίνει είναι αυτό:

Κώδικας: Επιλογή όλων

input1     name1    id1 
Δηλαδή δεν δίνει τη γραμμή που έχει null στο τελευταίο πεδίο.
Υποψιάζομαι ότι ίσως φταίει το ότι μέσα στο where υπάρχει συνθήκη και με το τρίτο πεδίο του table2.
Καμία ιδέα κανείς?

pimpogio
Δημοσιεύσεις: 1080
Εγγραφή: 28 Δεκ 2010 14:08

[Solved] Inner join, outer join, union και τα μυαλά στα κάγκελα

Δημοσίευση από pimpogio » 17 Ιούλ 2011 21:02

outer join θες βεβαια και με left θα κανεις δουλεια με ενωση δηλαδη UNION ALL
αν και κατι δεν εχεις γραψει καλα ποιο πανω

Άβαταρ μέλους
dva_dev
Script Master
Δημοσιεύσεις: 3790
Εγγραφή: 16 Σεπ 2005 01:32
Επικοινωνία:

[Solved] Inner join, outer join, union και τα μυαλά στα κάγκελα

Δημοσίευση από dva_dev » 17 Ιούλ 2011 22:04

Εγώ πάντως αδυνατώ ακόμα να καταλάβω τα επιθυμητά αποτελέσματα πως βγαίνουν.

billiaswhs
Δημοσιεύσεις: 346
Εγγραφή: 11 Νοέμ 2004 00:29
Επικοινωνία:

[Solved] Inner join, outer join, union και τα μυαλά στα κάγκελα

Δημοσίευση από billiaswhs » 17 Ιούλ 2011 22:28

κάνε δοκιμές με το where μέχρι να σου βγεί αλλιώς βάλε
cross join που είναι το καρτεσιανό γινόμενο των δύο
πίνακων και κάνε eliminate με dinstict αλλά δεν είναι ότι καλύτερο
για πολλέ εγγραφές αυτό

pimpogio
Δημοσιεύσεις: 1080
Εγγραφή: 28 Δεκ 2010 14:08

[Solved] Inner join, outer join, union και τα μυαλά στα κάγκελα

Δημοσίευση από pimpogio » 17 Ιούλ 2011 23:08

dva_dev έγραψε:Εγώ πάντως αδυνατώ ακόμα να καταλάβω τα επιθυμητά αποτελέσματα πως βγαίνουν.
++
και εγω γι αυτο ειπα οτι κατι δεν εχει γραψει καλα ποιο πανω

Άβαταρ μέλους
eirinikp
Δημοσιεύσεις: 90
Εγγραφή: 04 Οκτ 2010 12:59

[Solved] Inner join, outer join, union και τα μυαλά στα κάγκελα

Δημοσίευση από eirinikp » 18 Ιούλ 2011 12:00

pimpogio έγραψε:
dva_dev έγραψε:Εγώ πάντως αδυνατώ ακόμα να καταλάβω τα επιθυμητά αποτελέσματα πως βγαίνουν.
++
και εγω γι αυτο ειπα οτι κατι δεν εχει γραψει καλα ποιο πανω
Λοιπόν, επειδή είχα κάνει δοκιμές με τα περισσότερα από όσα είπατε, νομίζω ότι είναι καλύτερα να σας εξηγήσω πώς βγαίνουν τα επιθυμητά αποτελέσματα, διότι δεν έχω μπερδέψει τίποτα, ώστε να καταλάβετε τι θέλω να κάνω και να βρούμε μία άκρη όλοι μαζί:

Θέλω να επιλέξει τις εγγραφές που αν υπάρχουν μόνο στον table1 τότε να έχουν field3='something', ενώ αν αναφέρονται και στον table2 θα πρέπει ΚΑΙ το field3='something' ΚΑΙ το field4='somethingelse'

Άρα η πρώτη εγγραφή περνάει γιατί ανήκει στη δεύτερη κατηγορία (είναι και στους 2 πίνακες)
Η δεύτερη εγγραφή περνάει γιατί είναι στην πρώτη κατηγορία (μόνο στον table1).
Η τρίτη εγγραφή δεν περνάει γιατί field3 != 'something'
Η τέταρτη εγγραφή δεν περνάει γιατί ανήκει στη δεύτερη κατηγορία. Αυτό σημαίνει ότι παρόλο που field3='something', field4!='somethingelse'

Άβαταρ μέλους
dva_dev
Script Master
Δημοσιεύσεις: 3790
Εγγραφή: 16 Σεπ 2005 01:32
Επικοινωνία:

[Solved] Inner join, outer join, union και τα μυαλά στα κάγκελα

Δημοσίευση από dva_dev » 18 Ιούλ 2011 13:55

Η 4η εγγραφή για ποιό λόγο δεν πρέπει να φαίνεται;
Αφού είναι μόνο στον 1ο πίνακα όπως και η 2η εγγραφή.

Κώδικας: Επιλογή όλων

SELECT t.id, t.name, t2.id
FROM table1 t
LEFT OUTER JOIN table2 t2 ON t.id = t2.table1_id
WHERE t.field3 = 'something'
AND (t2.field4 = 'somethingelse' OR t2.field4 IS NULL)

Άβαταρ μέλους
eirinikp
Δημοσιεύσεις: 90
Εγγραφή: 04 Οκτ 2010 12:59

[Solved] Inner join, outer join, union και τα μυαλά στα κάγκελα

Δημοσίευση από eirinikp » 18 Ιούλ 2011 14:29

Sorry, τελικά είχα ένα λαθάκι στον table2: αντί να βάλω στην δεύτερη εγγραφή table1_id:input4, είχα βάλει name4. (Τώρα το άλλαξα). Ειλικρινά συγνώμη για το μπέρδεμα... :oops:
dva_dev έγραψε:Η 4η εγγραφή για ποιό λόγο δεν πρέπει να φαίνεται;
Αφού είναι μόνο στον 1ο πίνακα όπως και η 2η εγγραφή.

Κώδικας: Επιλογή όλων

SELECT t.id, t.name, t2.id
FROM table1 t
LEFT OUTER JOIN table2 t2 ON t.id = t2.table1_id
WHERE t.field3 = 'something'
AND (t2.field4 = 'somethingelse' OR t2.field4 IS NULL)
Μετά τη διόρθωση απαντάω, αν και τώρα μάλλον θα είναι πλέον κατανοητό:
Διότι έχει καταχώρηση και στον table2:

Κώδικας: Επιλογή όλων

id2           input4          gkouch
αλλά δεν πληρεί τις προϋποθέσεις για να φαίνεται.
Αν μία εγγραφή εμφανίζεται ΜΟΝΟ στον table1, πρέπει απλά να ισχύει
field3='something'
Αν μία εγγραφή εμφανίζεται ΚΑΙ στον table1 ΚΑΙ στον table2, πρέπει να ισχύει
field3='something' ΚΑΙ field4='somethingelse'

gvre
Δημοσιεύσεις: 992
Εγγραφή: 14 Οκτ 2010 11:34
Τοποθεσία: Ηράκλειο Κρήτης
Επικοινωνία:

[Solved] Inner join, outer join, union και τα μυαλά στα κάγκελα

Δημοσίευση από gvre » 18 Ιούλ 2011 17:28

Αν κατάλαβα καλά χρειάζεσαι κάτι σαν το παρακάτω

Κώδικας: Επιλογή όλων

SELECT t.id, t.name, t2.id, t2.field4  
FROM table1 t 
LEFT JOIN table2 t2 ON t.id = t2.table1_id  
WHERE t.field3 = 'something' AND t2.field4 IS NULL 
UNION 
SELECT t.id, t.name, t2.id, t2.field4  
FROM table1 t 
INNER JOIN table2 t2 ON t.id = t2.table1_id  
WHERE t.field3 = 'something' AND t2.field4 = 'somethingelse'
Edit: Χρησιμοποίησε αυτό που έστειλε ο dva_dev. Κάνει την ίδια δουλειά, είναι απλούστερο και εκτελείται ταχύτερα.

Άβαταρ μέλους
eirinikp
Δημοσιεύσεις: 90
Εγγραφή: 04 Οκτ 2010 12:59

[Solved] Inner join, outer join, union και τα μυαλά στα κάγκελα

Δημοσίευση από eirinikp » 18 Ιούλ 2011 21:54

Εντάξει, τελικά το έλεγξα. Πράγματι δούλεψε με τη λύση του dva_dev
Τη λύση του gvre δεν την έλεγξα, αφού μου είπε ότι η άλλη είναι πιο γρήγορη, επειδή είναι πολύ σημαντικό να εκτελώ γρήγορα queries.

Ουσιαστικά αυτό που δε γνώριζα ήταν το "IS NULL"

Σας ευχαριστώ πολύ όλους!!!

gvre
Δημοσιεύσεις: 992
Εγγραφή: 14 Οκτ 2010 11:34
Τοποθεσία: Ηράκλειο Κρήτης
Επικοινωνία:

[Solved] Inner join, outer join, union και τα μυαλά στα κάγκελα

Δημοσίευση από gvre » 18 Ιούλ 2011 22:38

Αν έχεις λίγα δεδομένα δε θα δεις σημαντικές διαφορές σε ταχύτητα. Όταν αποκτήσεις πολλές εγγραφές καλό είναι να δοκιμάσεις και τις 2 περιπτώσεις. Γενικά καλό είναι να δοκιμάζεις διαφορετικές λύσεις όταν έχεις πολλά data. Κάποια στιγμή ρίξε μια ματιά και στην explain.

Απάντηση

Επιστροφή στο “MySQL”

Μέλη σε σύνδεση

Μέλη σε αυτήν τη Δ. Συζήτηση: Δεν υπάρχουν εγγεγραμμένα μέλη και 0 επισκέπτες