2010-10-12 6 views
2

Voici donc ce que j'essaie de faire. Mon patron veut mettre tous les véhicules que nous avons sur notre page d'accueil et tirer au hasard 8 d'entre eux à la fois. La façon dont notre schéma de base de données est configuré a les produits et les catégories dans des tables séparées en utilisant une référence croisée pour localiser la catégorie dans laquelle le produit tombe. La table avec les catégories a un parent qui est un ID direct d'une autre catégorie. Alors voici le SQL que j'ai trouvé.SQL Sélection de produits dans une seule catégorie

SELECT  product.productID, 
       product.productSKU, 
       product.price, 
       product.name, 
      product.stateInd, 
       category.parentID, 
       category.categoryID, 
       prod_cat.productID FROM category 

LEFT JOIN prod_cat 
    ON prod_cat.categoryID = category.categoryID 
LEFT JOIN product 
    ON product.productID = prod_cat.productID 

WHERE category.parentID = <cfqueryparam value="#catID#" cfsqltype="cf_sql_varchar" /> AND product.name <> "" AND RAND() 

LIMIT 8 

J'espère que tout est logique. J'ai juste le plus de mal à tirer non seulement 8 produits, mais aussi à m'assurer que ces 8 produits sont uniques. Oh et j'ai essayé de mettre DISTINCT après la sélection mais le produit était encore sélectionné deux fois.

Merci!

Répondre

5

DISTINCT devrait fonctionner. Si ce n'est pas le cas, essayez de group by productId. Pour sélectionner des lignes aléatoires, choisissez rand() au lieu de la construction where rand().

La combinaison des deux:

WHERE category.parentID = <cfqueryparam value="#catID#" cfsqltype="cf_sql_varchar"/> 
     AND product.name <> "" 
GROUP BY 
     product.productID 
ORDER BY 
     RAND() 
LIMIT 8 
+0

fraîche Ok! Je travaillais là-dessus un peu plus et j'ai obtenu l'ordre par chose de rand a compris ... mais c'était encore la duplication. C'est à ce moment-là que j'ai réalisé que nous avions 2 produits avec le même nom, la même image juste des références différentes ... si ça a du sens :) Bref je vais essayer la commande par les choses aussi! Merci beaucoup! + –

0

Je aurait tirer les 8 produits uniques dans une sous-requête, puis utilisez que dans le reste de votre requête.

En pseudo-code très approximative:

select ... 
    from (select 8 distinct random product IDs from product table) p 
     left join prod_cat 
      on p.productID = prod_cat.productID 
     left join category 
      on prod_cat.categoryID = category.categoryID 
    ... 
+0

J'étais sur le point de publier le même .. Sélectionnez 8 produits en premier, puis faites les jointures. –

+0

Ok! J'aime ça aussi. Est-ce que cela améliorerait les performances? –

+0

@Nathan: Testez et comparez les deux versions. –

0

REMARQUE: Joe m'a battu pour cette réponse, mais je ne savais pas comment mettre le code en commentaire, alors voici ma réponse.

Je ne sais pas si categoryID donnera seule ligne ou plusieurs lignes pour votre entrée, si elle est seule rangée, vous pouvez très bien utiliser = au lieu de in

SELECT * 
    FROM (SELECT * FROM product 
     WHERE product.productID in (
      SELECT productID 
       FROM prod_cat 
      WHERE categoryID in ( 
        SELECT categoryID 
        FROM category 
        WHERE parentID = 
          <cfqueryparam 
          value="#catID#" 
          cfsqltype="cf_sql_varchar" /> 
          ) 
       AND name <> '' 
      ORDER BY rand() 
      LIMIT 8 
      ) p 
INNER JOIN prod_cat ON p.productID=prod_cat.productID 
INNER JOIN category ON prod_cat.categoryID=category.categoryID 
+0

Cool! Merci, je vais certainement devoir voir à propos de tester les deux façons! Merci de votre aide. MISE À JOUR: Juste essayé ... et malheureusement ma version de MySQL ne supporte pas certaines des fonctionnalités des sous-requêtes ci-dessus. Je souhaite vraiment que cela fonctionnerait voulu essayer: - / –

Questions connexes