αποφυγή OR και εμφωλευμένων Select

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

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

Απάντηση
Άβαταρ μέλους
MeTaL-RoY
Δημοσιεύσεις: 67
Εγγραφή: 12 Μαρ 2003 16:58
Τοποθεσία: Athens
Επικοινωνία:

αποφυγή OR και εμφωλευμένων Select

Δημοσίευση από MeTaL-RoY » 28 Οκτ 2007 19:28

Καλησπέρα,

Έχω ένα table που περιέχει τα 4 χρώματα τα οποία μπορεί να έχει κάθε αντικείμενο.

table(id, productname, color1,color2,color3,color4)

Ο χρήστης πρέπει να επιλέγει από ένα interface έως 4 τιμές χρωμάτων (μπορεί να είναι και ίδιες μεταξή τους) και να αναζητά αν υπάρχει αυτό το αντικείμενο (με τα συγκεκριμένα χρώματα). Τα χρώματα είναι 20 στον αριθμό.

Το πρόβλημα είναι ότι ο χρηστης μπορεί να επιλέξει λιγότερες από 4 τιμές και ότι η σειρά με την οποία δίνονται δεν είναι υποχρεωτικά ίδια με αυτή που αποθηκεύονται στη βάση.

Πχ αντικείμενο 1 κόκκινο κίτρινο μπλε κόκκινο

ο χρήστης ζητά να βρεί αντικείμενο με τα χρωμματα κόκκινο, κόκκινο μπλε και οτιδίποτε άλλο.

Υπάρχει τρόπος να καταφέρω κάτι τέτοιο χωρίς να γράψω 50 or ή 10 εμφωλευμένα select?

Άβαταρ μέλους
dik_
Δημοσιεύσεις: 476
Εγγραφή: 07 Ιουν 2007 11:28

αποφυγή OR και εμφωλευμένων Select

Δημοσίευση από dik_ » 01 Νοέμ 2007 15:50

Σίγουρα θα υπάρχουν και καύτεροι τρόποι που δεν μου έρχονται, αλλά να ένας:

Στο table βάζεις άλλο ένα column που περιέχει όλα τα χρώματα και κάνεις full text search πάνω σε αυτό το column, με + μπροστά από κάθε χρώμα που δίνει ο χρήστης:

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

SELECT *, MATCH(all_cols) AGAINST ('+red +green' IN BOOLEAN MODE) AS foundcols FROM test WHERE MATCH(all_cols) AGAINST ('+red +green' IN BOOLEAN MODE)
Σε αυτά:

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

CREATE TABLE test(
`cat_id` INT(10) unsigned PRIMARY KEY AUTO_INCREMENT,
`all_cols` VARCHAR(255)
)ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
INSERT INTO test (all_cols) VALUES ('red green blue');
INSERT INTO test (all_cols) VALUES ('red green yellow');
INSERT INTO test (all_cols) VALUES ('red yellow blue');
INSERT INTO test (all_cols) VALUES ('red blue black');
INSERT INTO test (all_cols) VALUES ('red black white');
INSERT INTO test (all_cols) VALUES ('red black purple green');
INSERT INTO test (all_cols) VALUES ('red black purple yellow');
INSERT INTO test (all_cols) VALUES ('yellow black red green');
με:

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

SELECT *, MATCH(all_cols) AGAINST ('+red +green +yellow' IN BOOLEAN MODE) AS foundcols FROM test WHERE MATCH(all_cols) AGAINST ('+red +green +yellow' IN BOOLEAN MODE)
παίρνεις κανονικά:

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

2  	red green yellow  	1
9 	yellow black red green 	1
που είναι αυτό που θέλεις.

Μπορείς εύκολα να φτιάξεις την extra column σε όλες τις υπάρχουσες γραμμές:

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

UPDATE test SET all_cols = CONCAT_WS(' ', color1, color2, color3, color4);

Άβαταρ μέλους
cordis
Administrator, [F|H]ounder, [C|S]EO
Δημοσιεύσεις: 27616
Εγγραφή: 09 Οκτ 1999 03:00
Τοποθεσία: Greece
Επικοινωνία:

αποφυγή OR και εμφωλευμένων Select

Δημοσίευση από cordis » 01 Νοέμ 2007 22:57

το πρόβλημά σου είναι η λάθος κανονικοποίηση.

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

table products(prod_id, prod_name)

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

table products_colors(prod_id, color)

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

select p.* 
from products p, products_colors c
where p.prod_id = c.prod_id
and c.color in ('green','yellow','moustarde','ktl')
Δεν απαντάω σε προσωπικά μηνύματα με ερωτήσεις που καλύπτονται από τις ενότητες του forum. Για ο,τι άλλο είμαι εδώ για εσάς.
- follow me @twitter

Απάντηση

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

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

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