Μια βοήθεια σε query please

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

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

Απάντηση
Άβαταρ μέλους
korgr
Honorary Member
Δημοσιεύσεις: 5067
Εγγραφή: 07 Οκτ 2008 18:30
Τοποθεσία: Corinth
Επικοινωνία:

Μια βοήθεια σε query please

Δημοσίευση από korgr » 19 Ιούλ 2015 21:05

Έστω ένας πίνακας `features` με 2 πεδία productID και variantID

Πως μπορούμε να βρούμε όλα τα productID που έχουν όλες τις δεδομένες variantID τιμές;

πχ αν δωθούν ως variantIDs τα 1,10,32 Πως θα έχουμε όλα τα productID που ανταποκρίνονται σε όλα αυτά τα variantIDs?

Το

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

select productID from features where variantID IN (1,10,32)
προφανώς θα μας δώσει τα προϊόντα που έχουν έστω και ένα από αυτά τα variantIDs.
Εγώ θέλω τα προϊόντα που έχουν οπωσδήποτε όλα αυτά τα variantIDs

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

Μια βοήθεια σε query please

Δημοσίευση από dva_dev » 19 Ιούλ 2015 21:33

Αν στον πίνακα σου έχεις unique index στο (productID, variantID) τότε μπορείς να κάνεις το εξής:

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

select productID, count(variantID) cv from features where variantID IN (1,10,32) group by productID having cv=3;
αλλιώς βάζεις και distinct

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

select productID, count(DISTINCT variantID) cv from features where variantID IN (1,10,32) group by productID having cv=3;
Προφανώς το cv=3 μπορείς να το υπολογίσεις από πριν στην php, όπως φτιάχνεις το string "1,10,32"

Άβαταρ μέλους
korgr
Honorary Member
Δημοσιεύσεις: 5067
Εγγραφή: 07 Οκτ 2008 18:30
Τοποθεσία: Corinth
Επικοινωνία:

Μια βοήθεια σε query please

Δημοσίευση από korgr » 19 Ιούλ 2015 21:52

Δυστυχώς δεν μπορώ να έχω unique index σε αυτά

Τα περιεχόμενα του πίνακα αυτή τη στιγμή είναι:
"productID" "variantID"
"4" "21"
"4" "8"
"4" "14"
"4" "26"
"4" "7"
"4" "3"
"5" "2"
"5" "8"
"5" "4"
"5" "25"
"5" "7"
"20" "1"
"20" "32"
"20" "33"
"21" "9"
"21" "14"
"21" "23"
"21" "18"
"21" "30"
"23" "31"
"23" "14"
"23" "35"
"23" "16"
"23" "1"
"23" "24"
"21" "21"
"31" "35"
"31" "15"
"31" "21"
"31" "23"
"31" "14"
"31" "30"
"20" "7"
"22" "10"
"22" "17"
"22" "1"
"22" "23"
"22" "14"
"22" "30"
Μόνο τα προϊόντα 20, 22 αντιστοιχούν στα variantIDs 1,10,32
Ό,τι και αν έχω δοκιμάσει με JOINS στον βασικό πίνακα `products` μου δίνει στα αποτελέσματα τα προϊόντα 20, 22, 23
Το προϊόν 23 όμως, εχει μόνο κάποια από τα variantIDs, όχι όλα!

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

Μια βοήθεια σε query please

Δημοσίευση από dva_dev » 19 Ιούλ 2015 22:05

Τότε θα πρέπει να παίξεις με το distict όπως είχα αναφέρει.

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

select productID, count(distinct variantID) cv from features where variantID IN (1,10,32) group by productID having cv=3;
Αλλά απ' ότι είδα στα data που έδωσες δεν υπάρχει ο συνδυασμός 1,10,32.
[edit]
Το product 20 δεν έχει το variant 10 και το product 22 δεν έχει το variant 32.
(εκτός και αν έχεις κι άλλες εγγραφές παρακάτω που δεν τις έβαλες).
[/edit]

Άβαταρ μέλους
korgr
Honorary Member
Δημοσιεύσεις: 5067
Εγγραφή: 07 Οκτ 2008 18:30
Τοποθεσία: Corinth
Επικοινωνία:

Μια βοήθεια σε query please

Δημοσίευση από korgr » 19 Ιούλ 2015 23:01

Στο παρουσίασα τελείως λάθος και ζητώ χίλια συγνώμη
Ο πίνακας `features` έχει και ένα πεδίο featureID το οποίο αντιστοιχεί στην ομάδα του κάθε variantID
Εγώ τελικά θέλω όλα τα προϊοντα που έχουν ένα ή περισσότερα variantIDs ανά ομάδα featureID
Εκεί έχω κολήσει

Τελικά τα περιεχόμενα είναι:
"productID" "variantID" "featureID"
"4" "21" "1"
"4" "8" "2"
"4" "14" "4"
"4" "26" "5"
"4" "7" "6"
"4" "3" "3"
"5" "2" "1"
"5" "8" "2"
"5" "4" "3"
"5" "25" "5"
"5" "7" "6"
"20" "1" "1"
"20" "32" "2"
"20" "33" "5"
"21" "9" "2"
"21" "14" "4"
"21" "23" "5"
"21" "18" "7"
"21" "30" "8"
"23" "31" "8"
"23" "14" "4"
"23" "35" "2"
"23" "16" "7"
"23" "1" "1"
"23" "24" "5"
"21" "21" "1"
"31" "35" "2"
"31" "15" "7"
"31" "21" "1"
"31" "23" "5"
"31" "14" "4"
"31" "30" "8"
"20" "7" "6"
"22" "10" "2"
"22" "17" "7"
"22" "1" "1"
"22" "23" "5"
"22" "14" "4"
"22" "30" "8"
Υπάρχει κάποιο μαγικό query? :D

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

Μια βοήθεια σε query please

Δημοσίευση από dva_dev » 20 Ιούλ 2015 02:49

Αν κατάλαβα καλά θέλεις τα productid που έχουν τουλάχιστον ένα variantid για όλα τα featureid που δίνεις.

Δοκίμασε κάτι τέτοιο

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

select productid,count(distinct featureid) CF
from features
where featureid in (2,3,5)
group by productid
having CF=3;

Άβαταρ μέλους
korgr
Honorary Member
Δημοσιεύσεις: 5067
Εγγραφή: 07 Οκτ 2008 18:30
Τοποθεσία: Corinth
Επικοινωνία:

Μια βοήθεια σε query please

Δημοσίευση από korgr » 20 Ιούλ 2015 08:09

Το συγκεκριμένο query το είχα δοκιμάσει κι εγώ τροποποιώντας τα προηγούμενα που έδωσες, αλλά επιστρέφουν μηδέν προϊόντα.

Τα featureid δεν τα έχω δεδομένα όταν κτίζω το query. Έχω δεδομένα μόνο τα variantid.
Αν σε βοηθάει, ο πίνακας που περιέχει τις ομαδοποιησεις των variantid είναι `product_features` (με πεδία id, name) και ο πίνακας που περιέχει τα variants των features είναι ο `feature_variants` (id, featureid, name)

πχ έχουμε feature λειτουργικο, RAM κλπ
και variants Windows, Android --- 1gb, 4gb και λοιπά

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

Μια βοήθεια σε query please

Δημοσίευση από dva_dev » 20 Ιούλ 2015 12:51

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

Λες ότι ξέρεις μόνο τα variant ids, το οποίο σημαίνει ότι αν δώσεις 3 variants, αυτά μπορεί να ανήκουν όλα στο ίδιο feature ή μπορεί να ανήκουν και σε 3 διαφορετικά.

Οπότε πρέπει να βρεις τα feature ids και να τα μετρήσεις (1).

Μετά πρέπει να δεις ότι τα προϊόντα σου έχουν τουλάχιστον αυτά τα features, και το πλήθος των features (2) είναι το ίδιο με αυτό που είχες μετρήσει πριν (1).

Οπότε έχουμε και λέμε

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

-- Βρίσκει τα ids των features από τα ids των variants που έχεις δώσει
select distinct featureid
from feature_variants
where id in (1,10,32);
Μετά έχουμε

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

-- Βρίσκουμε τα ids των features και το πλήθος των features (από τα ids των variants που έχουμε)
select featureid, count(featureid) tmpCF
from (
  select distinct featureid
  from feature_variants
  where id in (1,10,32)
) tmp_inner;
Και τελικά παίρνουμε

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

select productid
from
(

  -- φέρνει τα productids, μετράει και τα features των productids, φέρνει το πλήθος των features που είχε μετρήσει από τα ids των variants
  select productid, count(distinct features.featureid) CF, tmpCF
  from features
  inner join
  (

    -- Βρίσκουμε τα ids των features και το πλήθος των features (από τα ids των variants που έχουμε)
    select featureid, count(featureid) tmpCF
    from (

      -- βρίσκει τα featureids από τα variantids
      select distinct featureid
      from feature_variants
      where id in (1,10,32)

    ) tmp_inner

  ) tmp
  on (features.featureid = tmp.featureid)
  group by productid

) tmp_outer
where CF=tmpCF;
Αλλάζεις μόνο το (1,10,32)

Άβαταρ μέλους
korgr
Honorary Member
Δημοσιεύσεις: 5067
Εγγραφή: 07 Οκτ 2008 18:30
Τοποθεσία: Corinth
Επικοινωνία:

Μια βοήθεια σε query please

Δημοσίευση από korgr » 20 Ιούλ 2015 14:57

Το δοκίμασα αλλά δουλεύει σωστά μόνο όταν του δίνω ένα φίλτρο (variantID)
Μόλις του δώσω και δεύτερο (ακόμα και valid) μου επιστρέφει μηδέν προϊόντα.

Προς το παρών έκανα δουλειά με συνδυασμό mysql και PHP:

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

// πρώτα παίρνω τα featureIDs βάσει των δεδομένων variantIDs		
// με "select distinct featureID from features where variantID in (".$variantIDs.")"
// μετά τρέχω ανεξάρτητα queries όσα και οι ομάδες φίλτρων
$counter = 1;
foreach($featureIDs as $featureID){
${"filters_".$counter} = array();
$records = $db->getRecords("select distinct productID from features where variantID in (".$variantIDs.") and featureID=".$featureID, false);
foreach($records as $record){
${"filters_".$counter}[] = $record['productID'];
}
$counter ++;
}

// τέλος έχοντας τα αποτελέσματα σε arrays, φιλτράρω τα productIDs με την php function array_intersect για να βρω τα κοινά
$arrays = array();
for&#40;$n=1; $n <= count&#40;$featureIDs&#41;; $n++&#41;&#123;
$arrays&#91;&#93; =  $&#123;"filters_".$n&#125;;
&#125;
$productIDs = call_user_func_array&#40;'array_intersect', $arrays&#41;;
Προφανώς όχι ό,τι το καλύτερο από πλευράς performance, γι' αυτό και αν βρεθεί native mysql λύση θα ήταν το βέλτιστο!

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

Μια βοήθεια σε query please

Δημοσίευση από dva_dev » 20 Ιούλ 2015 16:36

Εχεις δίκιο. Εβαλα μερικά data για να το δοκιμάσω και θέλει μια μικρή αλλαγή.
Δοκίμασε αυτό:

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

select productid
from
&#40;
  -- φέρνει τα productids, μετράει και τα features των productids, φέρνει το πλήθος των features που είχε μετρήσει από τα ids των variants
  select productid, count&#40;distinct features.featureid&#41; CF, tmpCF
  from features
  inner join
  &#40;
    -- Βρίσκουμε τα ids των features και το πλήθος των features &#40;από τα ids των variants που έχουμε&#41;
    select
           featureid, tmpCF
    from
           &#40;select distinct featureid from feature_variants where id in &#40;1,10,31&#41;&#41; tmp_inner1,
           &#40;select count&#40;distinct featureid&#41; tmpCF from feature_variants where id in &#40;1,10,31&#41;&#41; tmp_inner2
  &#41; tmp
  on &#40;features.featureid = tmp.featureid&#41;
  group by productid

&#41; tmp_outer
where CF=tmpCF;
Αν δεν βγάζει τα σωστά αποτελέσματα δείξε μερικά data από τους πίνακες product_features και feature_variants για να τσεκάρω με τα ίδια δεδομένα.

Άβαταρ μέλους
korgr
Honorary Member
Δημοσιεύσεις: 5067
Εγγραφή: 07 Οκτ 2008 18:30
Τοποθεσία: Corinth
Επικοινωνία:

Μια βοήθεια σε query please

Δημοσίευση από korgr » 20 Ιούλ 2015 17:27

Τώρα βγάζει και προϊόντα που θα έπρεπε να "κόβει"
Σου επισυνάπτω τους πίνακες:
features
feature_variants
product_features
products

Τα περιτά πεδία αγνόησέ τα, αφορούν την πλατφόρμα μου.

Κάποια cases:
variantIDs = 1, 10, 32 πρέπει να επιστρέψει τα προϊόντα 20, 22
variantIDs = 1, 10, 32, 4 δεν πρέπει να επιστρέψει κανένα προϊόν
variantIDs = 1, 2, 8, 10, 23, 25 πρέπει να επιστρέψει τα προϊόντα 5, 22

Χίλια ευχαριστώ για τον χρόνο σου master :D
Συνημμένα
db.rar
(1.86 KiB) Μεταφορτώθηκε 107 φορές

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

Μια βοήθεια σε query please

Δημοσίευση από dva_dev » 21 Ιούλ 2015 01:40

Sorry που άργησα αλλά τώρα ξαναέκατσα σε υπολογιστή.
Θα απαντάω λίγο λίγο αναλόγως το πως θα πάει και το δικό μου ψάξιμο.

Τα variantids (1,10,32) δίνουν ουσιαστικά featureids τα (1,2).

Τα προϊόντα που έχουν και αυτά τα δύο feature ids είναι (πέρα από τα 20,22 που ανέφερες)
το 4 (γραμμές με id 1,2 στον πίνακα features),
το 5 (γραμμές με id 8,9),
το 21 (γραμμές με id 16,27),
το 23 (γραμμές με id 23,25),
το 31 (γραμμές με id 28,30)

Οπότε μου φαίνεται τουλάχιστον για τα variants (1,10,32) σωστό το αποτέλεσμα που φέρνει το query.
Επειδή όμως πιστεύω ότι θέλεις και κάτι ακόμα από αυτό που έχεις πει (γι αυτό και επιμένεις ότι φέρνει και πράγματα που δεν πρέπει) δοκίμασα να το ψάξω λίγο ακόμα και υποθέτω ότι όχι μόνο θέλεις να έχει τα featureids (1,2) αλλά και τα variantids (1,10,32).

Θα το κοιτάξω λίγο ακόμα.

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

Μια βοήθεια σε query please

Δημοσίευση από dva_dev » 21 Ιούλ 2015 02:39

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

select productid
from 
&#40; 
  select productid, count&#40;distinct features.featureid&#41; CF, tmpCF 
  from features 
  inner join &#40; 
    select featureid, tmpCF 
    from &#40;select featureid from feature_variants where id in &#40;1, 2, 8, 10, 23, 25&#41;&#41; tmp_inner1, 
         &#40;select count&#40;distinct featureid&#41; tmpCF from feature_variants where id in &#40;1, 2, 8, 10, 23, 25&#41;&#41; tmp_inner2 
  &#41; tmp 
  on &#40;features.featureid = tmp.featureid and features.variantID in &#40;1, 2, 8, 10, 23, 25&#41;&#41; 
  group by productid 

&#41; tmp_outer
where CF=tmpCF;
Εγώ δοκίμασα και βγαίνουν τα αποτελέσματα που είπες ότι πρέπει να βγαίνουν.
Για κάνε καμιά δοκιμή ακόμα...

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

Μια βοήθεια σε query please

Δημοσίευση από dva_dev » 21 Ιούλ 2015 03:17

...άκυρο...
Αύριο πάλι.

Άβαταρ μέλους
korgr
Honorary Member
Δημοσιεύσεις: 5067
Εγγραφή: 07 Οκτ 2008 18:30
Τοποθεσία: Corinth
Επικοινωνία:

Μια βοήθεια σε query please

Δημοσίευση από korgr » 21 Ιούλ 2015 04:52

Σωστά είπες πως αντιστοιχούν στα features 1 και 2 (λειτουργικο συστημα και διάσταση οθόνης)
Πάμε στα variantid τώρα. To variantid 1 είναι "windows8" και τα variantid 10,32 είναι 15-15.9" και 7-9.9"

Μόνο τα προϊόντα 20 και 22 έχουν windows8 αλλά και ταυτόχρονα ΜΙΑ ή περισσότερες διαστάσεις οθόνης (variantid 10, 32)

Τα προϊόντα 4 και 23 που ανέφερες έχουν λειτουργικό IOS ενώ το προϊόν 5 είναι Android
Εμείς ψάχνουμε μόνο Windows8
Το προϊόν 23 είναι μεν Windows8 αλλά δεν ανταποκρίνεται σε κάποια από τις αναλύσεις οθόνης που ζητάμε.

Γενικά χωρίζουμε τα variantid σε ομάδες ανά featureid και σε κάθε ομάδα πρέπει να ανταποκρίνεται ένα ή περισσότερα variantid.

Ελπίζω να είναι πιο κατανοητή η μεθοδολογία της αναζήτησης :D

Απάντηση

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

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

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