2013-01-17 4 views
0

J'ai trois tables avec ces domaines:requête SQL avec UNION, SELECT et assemblez

product_views: ProductMasterID, Date

product_clicks: ProductMasterID, Date

product_master: ProductMasterID, Category

quelqu'un Anytime voit un produit sur mon site, il ajoute une ligne à product_views. Quand quelqu'un clique sur un produit sur mon site, il ajoute une ligne à product_clicks

J'essaye d'écrire une requête SQL (en MySQL/PHP) qui va me montrer la popularité des produits. La popularité est le nombre de fois qu'il a été consulté et cliqué ensemble. Je veux être en mesure de choisir aussi une plage de dates, et dans une certaine catégorie.

Je peux le faire fonctionner sans les contraintes de date/catégorie. J'essaye maintenant d'ajouter dans la gamme de date. Voilà ce que j'ai jusqu'à présent, la popularité de la dernière semaine:

SELECT *, COUNT(*) AS Popularity FROM 

    (SELECT product_views.ProductMasterID, product_views.Date 
     FROM product_views 
     WHERE product_views.Date BETWEEN '".date('Y-m-d',strtotime('now'))."' 
      AND '".date('Y-m-d',strtotime('-7days'))."'"." 

UNION ALL 

    SELECT product_clicks.ProductMasterID,product_clicks.Date 
     FROM product_clicks 
     WHERE product_clicks.Date BETWEEN '".date('Y-m-d',strtotime('now'))."' 
      AND '".date('Y-m-d',strtotime('-7days'))."'".") a 

GROUP BY ProductMasterID ORDER BY Popularity DESC LIMIT 100" 

Sauf qu'il travail ne marche pas, il ne donne aucun résultat. Cependant, si je supprime l'une des clauses WHERE, cela fonctionne pour une raison quelconque, mais j'ai besoin des deux. Mes questions sont les suivantes:

  1. Comment faire fonctionner avec les deux clauses WHERE
  2. Comment faire la partie de la catégorie par exemple sélectionner uniquement les produits qui ont une catégorie de «nourriture». Je pense que je devrais faire un joint quelque part avec la table product_master, mais semble rusé.

Toute aide serait grandement apprécié.

Merci

+0

Je suppose une faute de frappe, mais quand quelqu'un clique sur un produit doit-il pas ajouter une ligne à 'product_clicks' au lieu de' product_views'? –

+0

@ user1986985 pourquoi voulez-vous avoir un syndicat ici?Puisque votre plage de dates est la même, vous pouvez joindre deux tables? – bonCodigo

+0

Désolé pour la réponse tardive, je pensais que je m'étais inscrit à l'alerte e-mail, et recevrait un e-mail lorsque quelqu'un a répondu à cela, mais n'a rien reçu! Kevin, oui un type, l'a corrigé. bonCodigo, je regarde votre code maintenant, je verrai si je peux le faire, puis je reviendrai vers vous. Merci – user1986985

Répondre

0

Si vous souhaitez utiliser un REJOIGNEZ, voici une solution:

Requête:

SELECT M.PMID, M.CATEGORY, 
(COALESCE(V.VCNT,0) + 
COALESCE(C.CCNT,0)) AS TOTAL_COUNT 
FROM Master M 
LEFT JOIN (SELECT PMID, COUNT(*) AS VCNT 
      FROM VIEWS 
      WHERE DATE between 
      DATE_ADD(NOW(), INTERVAL - 7 DAY) 
      and now() 
      GROUP BY PMID) V 
ON V.PMID = M.PMID 
LEFT JOIN (SELECT PMID, COUNT(*) AS CCNT 
      FROM CLICKS 
      WHERE DATE between 
      DATE_ADD(NOW(), INTERVAL - 7 DAY) 
      and now() 
      GROUP BY PMID) C 
ON C.PMID = M.PMID 
GROUP BY M.PMID 
; 

Résultats:

| PMID | CATEGORY | TOTAL_COUNT | 
--------------------------------- 
| 1 | Shoes |   6 | 
| 2 | Books |   4 | 
| 3 |  Food |   3 | 

Utilisation de l'UNION et juste pour la partie SQL:

SELECT ID, COUNT(*) AS Popularity FROM 
(
    (SELECT product_views.ProductMasterID AS ID, count(*) 
     FROM product_views 
     WHERE product_views.Date BETWEEN '".date('Y-m-d',strtotime('now'))."' 
      AND '".date('Y-m-d',strtotime('-7days'))."'"." 
     GROUP BY product_views.ProductMasterID) 

UNION ALL 

    (SELECT product_clicks.ProductMasterID AS ID, COUNT(*) 
     FROM product_clicks 
     WHERE product_clicks.Date BETWEEN '".date('Y-m-d',strtotime('now'))."' 
      AND '".date('Y-m-d',strtotime('-7days'))."'".") a 
    GROUP BY product_clicks.ProductMasterID) 

GROUP BY ProductMasterID 
ORDER BY Popularity DESC LIMIT 100" 

Comment cela?

SELECT M.PMID, M.CATEGORY, COUNT(V.PMID), COUNT(C.PMID) 
FROM MASTER M 
LEFT JOIN VIEWS V 
ON V.PMID = M.PMID 
LEFT JOIN CLICKS C 
ON C.PMID = M.PMID 
WHERE V.DATE BETWEEN NOW() AND NOW() INTERVAL - 7 DAY 
AND C.DATE BETWEEN NOW() AND NOW() INTERVAL 7 DAY 
GROUP BY M.PMID, V.DATE, C.DATE 
; 

+0

Merci beaucoup bonCodigo, votre solution JOIN a travaillé un régal! Ce site SQLFIDDLE est utile, il l'utilisera dorénavant pour toutes les requêtes particulièrement délicates. – user1986985

+0

@ user1986985 heureux d'entendre cela et heureux que vous l'avez fait travailler :) Faites-nous savoir si vous avez d'autres questions. [Veuillez cocher la réponse si tout va bien avec votre question] (http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work). Vous pouvez cliquer sur la coche près des boutons upvote. Donc, la communauté sait que votre question est résolue. – bonCodigo