2010-11-24 7 views
0

je tableaux suivants
1) Produits (ProductID, nom, description, prix)
2) Ventes (salesid, ProductID, BUYERNAME, BuyerEmail, état)
3) ProductViews (viewId, ProductID)
MySQL Query pour extraire des données de plusieurs tables

maintenant, il me faut une requête qui peut produire comme
          ProductID           ProductName           Prix           TOTALVIEWS           TotalSales

Aide appréciée, merci.

+0

est-il une quantité dans la table de vente? ou est-ce une rangée par vente? –

Répondre

1
SELECT p.productid, p.name, p.price, COUNT(pv.viewid) AS totalviews, COUNT(s.salesid) AS totalsales 
FROM Products p 
LEFT JOIN Sales s ON s.productid = p.productid 
LEFT JOIN ProductViews pv ON pv.productid = p.productid 
GROUP BY p.productid, p.name, p.price 

groupe étendu par pour être complet, mais il pourrait juste être p.productid.

+0

merci, mais cette requête est-elle optimisée ou je dois faire quelque chose pour l'optimiser? –

+0

En supposant que vous avez des index sur ProductID sur chacune des tables c'est la requête la plus optimisée que vous pouvez avoir. Les sous-sélections sont toujours désagréables. – methodin

+0

Dans cet exemple, les trois tables doivent avoir un INDEX sur productid. Cela rendra la requête/jointures super rapide même si elles deviennent grandes. Toujours INDEX vos tables correctement et utilisez JOINs où vous le pouvez. – methodin

1

Vous pouvez utiliser les sous-requêtes pour obtenir le nombre de vues et les ventes:

SELECT 
    a.productid, 
    a.name, 
    a.price, 
    (SELECT COUNT(b.viewid) 
    FROM ProductViews b 
    WHERE b.productid = a.productid) as TotalViews, 
    (SELECT COUNT(c.salesid) 
    FROM Sales c 
    WHERE c.productid = a.productid) as TotalSales 
FROM 
    Products a 
+0

merci, mais cette requête est-elle optimisée ou je dois faire quelque chose pour l'optimiser? –

+0

Gr8 réponse. Mais cela nécessite peu de modifications. Voir ma réponse pour le même –

0
Select p.ProductID, p.ProductName, p.Price, s.c as TotalSales, v.c as TotalViews 
FROM Products p 
INNER JOIN (select productid, count(*) as c from Sales group by productid) s 
    ON s.productId = p.productid 
INNER JOIN (select productid, count(*) as c from ProductViews group by productid) v 
    ON p.productId = v.productid 

Si vous avez un produit qui ne dispose pas d'une vente ou d'une vue que vous aurez besoin de se joindre à gauche à la place

+0

merci, mais cette requête est-elle optimisée ou je dois faire quelque chose pour l'optimiser? –

+0

c'est juste une façon de le faire - utiliser expliquer ou similaire et faire des tests pour le savoir. –

0
SELECT a.productid, a.name, a.price, (

SELECT COUNT(b.viewid) 
FROM ProductViews b 
WHERE b.productid = a.productid 
) AS TotalViews, (

SELECT COUNT(c.salesid) 
FROM Sales c 
WHERE c.productid = a.productid 
) AS TotalSales 

FROM products a 
+0

Si vous avez des tables indexées appropriées, les sous-sélections pour les rollups ne sont jamais efficaces. – methodin

+0

ce que cela signifie? Je voudrais en savoir plus de vous, pouvez-vous préciser plus @methodin –

+0

Tout sous select nécessite la DB pour créer une table temporaire, en mémoire, sans index. Bien sûr, c'est terriblement lent. La façon correcte de gérer les requêtes de ce type consiste à INDEX vos tables sur les colonnes utilisées dans la clause de jointure et d'utiliser INNER/LEFT JOINs et un GROUP BY. Voir ma réponse pour plus d'élaboration. Ajoutez EXPLAIN avant votre requête pour voir ce que fera la DB. – methodin

Questions connexes