Προς το περιεχόμενο

Mysql join, union, temporary table ή κάτι άλλο?


hdonoblepsias

Προτεινόμενες αναρτήσεις

Καλησπέρα. Με ταλαιπωρεί ένα πρόβλημα 2 μέρες τώρα και δεν μπορώ να βρω λύση. Ρώτησα και έναν φίλο μου τηλεφωνικά αλλά δεν μπορούσα να εξηγήσω και πολύ καλά τι θέλω.

Έχω 2 tables σε μία βάση. πχ. Φρούτα και Λαχανικά.

Οπότε το πρώτο table ειναι πχ.

image.png.39f32f43515478a83473fbd8c585c82e.png

και το 2ο ειναι

image.png.596af66c2ff664707b9451896187a49d.png

Και θέλω να τα ενώσω ωστε να κάνω για παράδειγμα το παρακάτω

image.png.a2ef2951c96fb03cb17ea50decd80e76.png

Ποια είναι η καλύτερη λύση για κάτι τέτοιο.

1) Join. Δοκίμασα αλλά δεν έβγαλα άκρη;

2) Join (LEFT, RIGHT κλπ); Δεν είμαι εξοικειωμένος αλλά αν αυτή είναι η λύση, να το ψάξω.

3) Temporary Table; Ούτε με αυτό είμαι εξοικειωμένος αλλά αν αυτή είναι η λύση, να το ψάξω.

4) Union. Αυτό έψαξα και μέχρι ένα σημείο τα κατάφερα. Δηλαδή έφτιαξα κάτι τέτοιο...

    SELECT frouto_name as name, frouto_posotita, frouto_id as posotita FROM frouta
    UNION ALL
    SELECT laxaniko_name as name, laxaniko_posotita as posotita, laxaniko_id FROM laxanika
    ORDER BY posotita;

Τα frouto_id και laxaniko_id δεν τα έβαλα "as id" για να παίξω με το if που δείχνω παρακάτω.

Οπότε στην php μου στην λούπα της foreach έκανα κάτι τέτοιο.
 

 <td><?php echo result->posotita;?></td>
 <td><?php echo result->name;?></td>

δούλεψε.

Στο τρίτο column προσπάθησα να κάνω κάτι τέτοιο.

        <?php if($result->frouto_id != ""  &&  $result->frouto_id != NULL)
        {
        $typos= "Frouto";
        } else {
        $typos= "Laxaniko";
        }?>

οπότε το τρίτο <td> τό εκανα.

<td><?php echo $typos;?></td>

Το πρόβλημα είναι οτι ακόμα και στην περίπτωση του laxanikou, σετάρεται ως frouto. Δηλαδή γεμίζει 8 frouto_id ακόμα και με αυτά των λαχανικών. Και το laxaniko_id είναι άδειο σε όλα.

 

 

 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημοσ. (επεξεργασμένο)

Άσχετα με το πρόβλημα , αφού οι 2 πίνακες έχουν την ίδια δομή , γιατί δεν είναι ένας πίνακας που να έχει το id και άλλη μία κολώνα που να είναι η κατηγορία? (φρούτο , λαχανικό, κτλ .) ?

Επίσης αν δεν έχεις κλειδί για τις εγγραφές id,name τότε θα έχεις διπλές εγγραφές και δεν θα δουλέψει το union

Τέλος για το πρόβλημα σου , έχει κάθος το query και ορίζεις στο πρώτο select posotita το frouto_id αντί για το frouto_posotita

Οπότε το σωστό είναι αυτό

  SELECT frouto_name as name, frouto_posotita as posotita, frouto_id as id FROM frouta
  UNION ALL
  SELECT laxaniko_name as name, laxaniko_posotita as posotita, laxaniko_id as id FROM laxanika
  ORDER BY posotita;

Αλλά επειδή θα επιστρέφει κολώνα με όνομα id και όχι frouto_id / laxaniko_id τότε δεν θα σου παίξει το if.

Οπότε μπορείς να γράψεις το παρακάτω το οποίο θα σου επιστρέφει 0 για να ξεγελάσεις το union και να παίξει

  SELECT frouto_name as name, frouto_posotita as posotita, frouto_id , 0 as laxaniko_id FROM frouta
  UNION ALL
  SELECT laxaniko_name as name, laxaniko_posotita as posotita, 0 as frouto_id,laxaniko_id  FROM laxanika
  ORDER BY posotita;

Αλλάζεις το if να μην κοιτάει αν είναι κενό αλλά αν είναι 0. Και έτσι καταλαβαίνει αν είναι φρούτο ή λαχανικό

Σίγουρα είναι σωστό το design του πίνακα?

Αυτά , αν έχει κάποιος καλύτερη ιδέα θα μας πεί :D

Πάρε και το link για το sqlfiddle

http://sqlfiddle.com/#!9/b5a4f/7/0

Υ.Γ. Παίζει και με join αλλά βαριέμαι να το γράψω :)

 

Επεξ/σία από tsofras
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

SELECT frouto_name as name, frouto_posotita as posotita, 'Frouto' as eidos FROM frouta
  UNION ALL
  SELECT laxaniko_name as name, laxaniko_posotita as posotita, 'Laxaniko' as eidos FROM laxanika
  ORDER BY posotita;

Επίσης μπορεί να γίνει και απ' ευθείας αυτό, δεν έχω καταλάβει γιατί πρέπει να κάνεις assign από την PHP

 

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

4 ώρες πριν, tsofras είπε

Άσχετα με το πρόβλημα , αφού οι 2 πίνακες έχουν την ίδια δομή , γιατί δεν είναι ένας πίνακας που να έχει το id και άλλη μία κολώνα που να είναι η κατηγορία? (φρούτο , λαχανικό, κτλ .) ?

Προφανώς ειναι ασκηση που ζηταει union

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

4 ώρες πριν, tolhc1234 είπε

SELECT frouto_name as name, frouto_posotita as posotita, 'Frouto' as eidos FROM frouta
  UNION ALL
  SELECT laxaniko_name as name, laxaniko_posotita as posotita, 'Laxaniko' as eidos FROM laxanika
  ORDER BY posotita;

Επίσης μπορεί να γίνει και απ' ευθείας αυτό, δεν έχω καταλάβει γιατί πρέπει να κάνεις assign από την PHP

Πως εννοεις μπορει να γινει?

2 ώρες πριν, παπι είπε

Προφανώς ειναι ασκηση που ζηταει union

Οχι δεν ειναι ασκηση, αλλα οπως εχω γεμισει τους πινακες, δεν ξερω πως αλλιως να το κανω

7 ώρες πριν, tsofras είπε

Άσχετα με το πρόβλημα , αφού οι 2 πίνακες έχουν την ίδια δομή , γιατί δεν είναι ένας πίνακας που να έχει το id και άλλη μία κολώνα που να είναι η κατηγορία? (φρούτο , λαχανικό, κτλ .) ?

Επίσης αν δεν έχεις κλειδί για τις εγγραφές id,name τότε θα έχεις διπλές εγγραφές και δεν θα δουλέψει το union

Τέλος για το πρόβλημα σου , έχει κάθος το query και ορίζεις στο πρώτο select posotita το frouto_id αντί για το frouto_posotita

Οπότε το σωστό είναι αυτό


  SELECT frouto_name as name, frouto_posotita as posotita, frouto_id as id FROM frouta
  UNION ALL
  SELECT laxaniko_name as name, laxaniko_posotita as posotita, laxaniko_id as id FROM laxanika
  ORDER BY posotita;

Αλλά επειδή θα επιστρέφει κολώνα με όνομα id και όχι frouto_id / laxaniko_id τότε δεν θα σου παίξει το if.

Οπότε μπορείς να γράψεις το παρακάτω το οποίο θα σου επιστρέφει 0 για να ξεγελάσεις το union και να παίξει


  SELECT frouto_name as name, frouto_posotita as posotita, frouto_id , 0 as laxaniko_id FROM frouta
  UNION ALL
  SELECT laxaniko_name as name, laxaniko_posotita as posotita, 0 as frouto_id,laxaniko_id  FROM laxanika
  ORDER BY posotita;

Αλλάζεις το if να μην κοιτάει αν είναι κενό αλλά αν είναι 0. Και έτσι καταλαβαίνει αν είναι φρούτο ή λαχανικό

Σίγουρα είναι σωστό το design του πίνακα?

Αυτά , αν έχει κάποιος καλύτερη ιδέα θα μας πεί :D

Πάρε και το link για το sqlfiddle

http://sqlfiddle.com/#!9/b5a4f/7/0

Υ.Γ. Παίζει και με join αλλά βαριέμαι να το γράψω :)

Σε ευχαριστω θα τα δοκιμασω αυριο το μεσημερι

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Σε 1 Union πρέπει οι πίνακες να έχουν ακριβώς τα ίδια ονόματα..με ίδιο datatype....αν κάτι δεν είναι σωστό το Union δεν θα δουλέψει...γιαυτή ακριβώς την περίπτωση δουλευούμε με alias και εκάστοτε και με fake fields...η σωστή λύσεη είναι 1 κοινός πίνακας με 1 extra field η κατηγοροποιηση όπως πρότεινε ο tsofras.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

7 ώρες πριν, hdonoblepsias είπε

Πως εννοεις μπορει να γινει?

 

Εννοεί ότι δεν χρειάζεται να γράψεις if/else για να χτίζεις μόνος σου το είδος σε Frouto / Laxaniko , θα στο επιστρέφει το query και απλά θα τυπώνεις το eidos.

<td><?php echo result->posotita;?></td>
<td><?php echo result->name;?></td>
<td><?php echo result->eidos;?></td>

 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Το παραπάνω SELECT του @tsofras δούλεψε μια χαρά. Δηλαδή μπορώ να το αφήσω έτσι. Δεν έχω την δυνατότητα να φτιάξω αλλιώς τους πίνακες γιατί χρησιμοποιούντε σε πολλά  queries μέσα στο site. Μπορώ όμως να προσθέσω κάποια columns.

Οπότε στο παραπάνω παράδειγμα (το οποίο επαναλαμβάνω δουλεύει με αυτό που πρότεινε ο @tsofras), θα ήταν καλύτερο απο θέμα βελτιστοποίησης να εισάγω και στα 2 tables ένα ακόμα column που θα λέγεται eidos και εκεί να εισάγω ένα int οπού πχ 1= frouto, 2 = laxaniko κλπ?

19 ώρες πριν, tsofras είπε

Επίσης αν δεν έχεις κλειδί για τις εγγραφές id,name τότε θα έχεις διπλές εγγραφές και δεν θα δουλέψει το union

Καταλαβαίνω τι μου λες, θέλω τις διπλοεγραφές. Βασικά στο παράδειγμα που σκέφτηκα (αυτό σκέφτηκα εκείνη την στιγμή), καταλάβατε τον μηχανισμό που θέλω να εμφανίζονται και με βοηθήσατε. Στην ουσία αυτό που φτιάχνω είναι του στυλ

image.png.21e83157ad32511f95ad451e0c897622.png

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

8 λεπτά πριν, hdonoblepsias είπε

Το παραπάνω SELECT του @tsofras δούλεψε μια χαρά. Δηλαδή μπορώ να το αφήσω έτσι. Δεν έχω την δυνατότητα να φτιάξω αλλιώς τους πίνακες γιατί χρησιμοποιούντε σε πολλά  queries μέσα στο site. Μπορώ όμως να προσθέσω κάποια columns.

Οπότε στο παραπάνω παράδειγμα (το οποίο επαναλαμβάνω δουλεύει με αυτό που πρότεινε ο @tsofras), θα ήταν καλύτερο απο θέμα βελτιστοποίησης να εισάγω και στα 2 tables ένα ακόμα column που θα λέγεται eidos και εκεί να εισάγω ένα int οπού πχ 1= frouto, 2 = laxaniko κλπ?

Καταλαβαίνω τι μου λες, θέλω τις διπλοεγραφές. Βασικά στο παράδειγμα που σκέφτηκα (αυτό σκέφτηκα εκείνη την στιγμή), καταλάβατε τον μηχανισμό που θέλω να εμφανίζονται και με βοηθήσατε. Στην ουσία αυτό που φτιάχνω είναι του στυλ

image.png.21e83157ad32511f95ad451e0c897622.png

Αν δεν φτιάξεις έναν πίνακα δεν νομίζω θα κερδίσεις κάτι με την εισαγωγή μίας dummy κολώνας που θα πρέπει να την διαβάζεις ενώ θα είναι πάντα ίδια η εγγραφή σε όλο τον πίνακα. Καλύτερα να το κάνεις με το select.

Αν φτιάχνεις ένα site έτσι για τον χαβαλέ τότε οκ μην το κάνεις refactor αν σου είναι βαρύ.

Αν φτιάχνεις κάτι το οποίο όμως θα συνεχίσεις να κάνεις ανάπτυξη κτλ. καλύτερα να επενδύσεις χρόνο τώρα να το αλλάξεις γιατί μετά θα το βρείς μπροστά σου πάντως.

Εππισης αν το φτιάξεις σωστά , θα έχεις ένα σωστό καλούπι για να χτίσεις παρόμοια sites με τον κώδικα που έχεις ήδη.

Δλδ τώρα είναι για έσοδα/εξοδα

Αν σου ζητήσει κάποιος να φτιάξεις κάτι αντίστοιχο που θα είναι όντως για λαχανικά/φρούτα θα πρέπει να τα κάνεις όλα copy paste (βάση , queries, οθόνες κτλ.) και να αλλάζεις τους πίνακες και τα queries.

Αν τον κάνεις ένα μετα το χρησιμοποιείς όπου θέλεις :D

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

5 ώρες πριν, tsofras είπε

Αν δεν φτιάξεις έναν πίνακα δεν νομίζω θα κερδίσεις κάτι με την εισαγωγή μίας dummy κολώνας που θα πρέπει να την διαβάζεις ενώ θα είναι πάντα ίδια η εγγραφή σε όλο τον πίνακα.

Άκουσα την συμβουλή σου και έφτιαξα τελικά έναν πίνακα "κινησεις" που εκει θα συγκεντρώνω τα στοιχεία που θέλω (αν αυτό εννούσες). Τωρα μπορώ και τα χειρίζομαι πολύ καλύτερα.

Αν σου ζητήσει κάποιος να φτιάξεις κάτι αντίστοιχο που θα είναι όντως για λαχανικά/φρούτα θα πρέπει να τα κάνεις όλα copy paste (βάση , queries, οθόνες κτλ.) και να αλλάζεις τους πίνακες και τα queries.

Γαμώτο, κάπως δεν μπορώ να ξαναχρησιμοποιώ αυτά που έχω φτιάξει και αλλού. Κάπως μπερδέυομαι με τις αλλαγές που πρέπει να κάνω στο νέο project. Θα με βόλευε αν υπήρχε όμως κάτι που να μπορώ να φτιάξω κάτι σαν δικό μου documentation που θα έχω ένα παράδειγμα με όλα αυτά που χρησιμοποιώ. Δηλαδή να μπορώ να δώ μία function που έχω φτιάξει για να κάνω κάτι και να την παίρνω με copy paste, να την εισάγω στο νέο project και απλά να κάνω μικροαλλαγές.

 

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

3 ώρες πριν, hdonoblepsias είπε
8 ώρες πριν, tsofras είπε

Αν δεν φτιάξεις έναν πίνακα δεν νομίζω θα κερδίσεις κάτι με την εισαγωγή μίας dummy κολώνας που θα πρέπει να την διαβάζεις ενώ θα είναι πάντα ίδια η εγγραφή σε όλο τον πίνακα.

Άκουσα την συμβουλή σου και έφτιαξα τελικά έναν πίνακα "κινησεις" που εκει θα συγκεντρώνω τα στοιχεία που θέλω (αν αυτό εννούσες). Τωρα μπορώ και τα χειρίζομαι πολύ καλύτερα.

Αν σου ζητήσει κάποιος να φτιάξεις κάτι αντίστοιχο που θα είναι όντως για λαχανικά/φρούτα θα πρέπει να τα κάνεις όλα copy paste (βάση , queries, οθόνες κτλ.) και να αλλάζεις τους πίνακες και τα queries.

Γαμώτο, κάπως δεν μπορώ να ξαναχρησιμοποιώ αυτά που έχω φτιάξει και αλλού. Κάπως μπερδέυομαι με τις αλλαγές που πρέπει να κάνω στο νέο project. Θα με βόλευε αν υπήρχε όμως κάτι που να μπορώ να φτιάξω κάτι σαν δικό μου documentation που θα έχω ένα παράδειγμα με όλα αυτά που χρησιμοποιώ. Δηλαδή να μπορώ να δώ μία function που έχω φτιάξει για να κάνω κάτι και να την παίρνω με copy paste, να την εισάγω στο νέο project και απλά να κάνω μικροαλλαγές.

Κοίτα δεν ασχολούμαι καθόλου με php αλλά όπως σε όλα η λογική είναι κοινή , φτιάξε διάφορα αρχεία με τα functions που έχεις και να τα κάνεις include εκεί που θέλεις.

Τώρα αν η php υποστηρίζει πολυμορφισμό ή κληρονομικότητα δεν το ξέρω οπότε ρίξε διάβασμα να μάθεις 👍

  • Thanks 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...