SQL从数据库返回最畅销的产品

时间:2014-12-15 04:34:17

标签: sql sql-server

我有一个SQL查询,可以从数据库返回27个销售产品:

SELECT TOP 27 ROW_NUMBER() OVER (ORDER BY ttP.ProductName ASC) AS Rno, ttP.*, ttI.ImageID FROM tblProducts AS ttP 
LEFT OUTER JOIN (SELECT ImageID, ProductID FROM tblImages WHERE Main = 1) AS ttI ON ttP.ProductID = ttI.ProductID 
LEFT OUTER JOIN (SELECT TOP 27 ProductID, SUM(Quantity) AS NumSold FROM tblOrderItems GROUP BY ProductID ORDER BY SUM(Quantity) DESC) 
AS ttOI ON ttP.ProductID = ttOI.ProductID 
WHERE ttP.ProductVisibleOnline = 1 AND ttP.CollectionID IS NULL 
AND ttOI.NumSold IS NOT NULL 
ORDER BY ttOI.NumSold DESC, ttP.ProductName ASC

我想添加以下WHERE子句,以便返回具有特定功能的前27个产品

WHERE ttP.ProductID IN (SELECT ProductID FROM tblProductsFeatures WHERE FeatureID = 3)

所以我继续把它添加到声明的最后并以此结束:

SELECT TOP 27 ROW_NUMBER() OVER (ORDER BY ttP.ProductName ASC) AS Rno, ttP.*, ttI.ImageID FROM tblProducts AS ttP 
LEFT OUTER JOIN (SELECT ImageID, ProductID FROM tblImages WHERE Main = 1) AS ttI ON ttP.ProductID = ttI.ProductID 
LEFT OUTER JOIN (SELECT TOP 27 ProductID, SUM(Quantity) AS NumSold FROM tblOrderItems GROUP BY ProductID ORDER BY SUM(Quantity) DESC) 
AS ttOI ON ttP.ProductID = ttOI.ProductID 
WHERE ttP.ProductVisibleOnline = 1 AND ttP.CollectionID IS NULL 
AND ttOI.NumSold IS NOT NULL 
AND ttP.ProductID IN (SELECT ProductID FROM tblProductsFeatures WHERE FeatureID = 3)
ORDER BY ttOI.NumSold DESC, ttP.ProductName ASC

这将返回11条记录,这些记录是没有where子句的前27个销售产品的子集。我不明白我在哪里可以放置where子句,以便获得FeatureID = 3的前27个畅销产品。非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

看看你如何加入tblOrderItems表,或许这就是你要找的东西:

SELECT TOP 27 ROW_NUMBER() OVER (ORDER BY ttP.ProductName ASC) AS Rno, 
              ttP.*, ttI.ImageID 
FROM tblProducts AS ttP 
    LEFT OUTER JOIN (
        SELECT ImageID, ProductID
        FROM tblImages 
        WHERE Main = 1) AS ttI ON ttP.ProductID = ttI.ProductID 
    INNER JOIN (
        SELECT TOP 27 ProductID, SUM(Quantity) AS NumSold 
        FROM tblOrderItems 
        WHERE ProductID IN (SELECT ProductID 
                            FROM tblProductsFeatures 
                            WHERE FeatureID = 3)
        GROUP BY ProductID 
        ORDER BY SUM(Quantity) DESC) AS ttOI ON ttP.ProductID = ttOI.ProductID 
WHERE ttP.ProductVisibleOnline = 1 
    AND ttP.CollectionID IS NULL 
ORDER BY ttOI.NumSold DESC, 
    ttP.ProductName ASC

这也会将outer joins之一替换为inner join,并删除部分where条件。

答案 1 :(得分:0)

这里的问题是您在派生表(SELECT TOP 27 ...AS ttOI)中找到前27个产品,但随后在外部选择中应用了更多过滤器。这样可以进一步将产品行数从27减少到11,因为外部过滤器消除的行不会以某种方式强制内部27限制根据新标准重新评估。

我建议您在加入其他表格之前对符合条件的产品进行所有过滤,并对产品的受欢迎程度进行排名。 另请注意,如果产品有多个图像,您可以重复产品吗?

SELECT ROW_NUMBER() OVER (ORDER BY ttP.ProductName ASC) AS Rno, 
       ttP.*, ttI.ImageID 
FROM 
  tblProducts AS ttP
  INNER JOIN
  (
    SELECT TOP 27 ttp.ProductId, SUM(ttOI.Quantity) AS NumSold
    FROM tblProducts AS ttP 
      INNER JOIN tblOrderItems ttOI
       ON ttP.ProductID = ttOI.ProductID 
      INNER JOIN tblProductsFeatures tPF
       ON ttP.ProductID = tPF.ProductID
    WHERE ttP.ProductVisibleOnline = 1 
      AND ttP.CollectionID IS NULL 
      AND ttOI.NumSold IS NOT NULL 
      AND tPF.FeatureID = 3
    GROUP BY ttp.ProductID 
    ORDER BY SUM(Quantity) DESC) AS ep -- Eligible products
  ON ttP.ProductID = ep.ProductID
LEFT OUTER JOIN -- Duplicate Rows if there is more than one image here
  tblImages AS ttI
   ON ttP.ProductID = ttI.ProductID 
   AND ttI.Main = 1
ORDER BY ep.NumSold DESC, ttP.ProductName ASC;