2009-11-23 99 views
0

对此查询有问题。记录返回,但没有分组通过product_id这是我想要的。如果我通过选项从组中删除其他字段,那么我得到一个不包含在group by或aggregate函数中的错误字段。sql查询问题

感谢您的帮助

SELECT 
    o.Product_ID, i.producttitle, i.URLimage,i.price, 
    i.customfield2, i.season, i.active, i.discontinued, 
    i.opttitle1, i.opttitle2, i.opttitle3, 
     SUM(CASE WHEN processdate BETWEEN '2009-08-01 00:00:00.000' 
       AND '2009-10-31 23:59:00.000' 
      THEN o.sprice ELSE 0 END) AS totalprice_date1, 
     SUM(CASE WHEN processdate BETWEEN '2009-11-01 00:00:00.000' 
       AND '2009-12-31 23:59:00.000' 
      THEN o.sprice ELSE 0 END) AS totalprice_date2, 
     SUM(CASE WHEN processdate BETWEEN '2009-08-01 00:00:00.000' 
       AND '2009-10-31 23:59:00.000' 
      THEN o.Qty ELSE 0 END) AS qtysold_date1, 
     SUM(CASE WHEN processdate BETWEEN '2009-11-01 00:00:00.000' 
       AND '2009-12-31 23:59:00.000' 
      THEN o.Qty ELSE 0 END) AS qtysold_date2 
    FROM dbo.getskusold o 
     inner join imagereport i 
      on o.product_id = i.product_id 
    GROUP BY o.Product_ID, i.producttitle, i.URLimage, 
     i.price, i.customfield2, i.season, 
     i.active, i.discontinued, i.opttitle1, 
     i.opttitle2, i.opttitle3 
+1

您的SQL看起来正确。 “他们没有按照product_id分组”是什么意思?你能提供一个样本输出:(a)你得到什么和(b)你想得到什么? – Heinzi 2009-11-23 18:04:36

+0

如果产品具有相同的product_id,那么它应该合并产品的时候会返回同一产品。 – jeff 2009-11-23 18:07:33

+0

它将为dbo.getskusold和imagereport之间的每个连接结果返回一行,而不是每个product_id的唯一行。 – 2009-11-23 18:09:54

回答

3

如果这是SQL Server中,分组是根据GROUP BY子句中列出的所有领域,因此,如果任何其他字段相同的product_id是不同的,他们将被分类为单独的行。

您要么停止输出不同的字段,要么选择将它们聚合并指定您想要的多个值中的哪一个(最小值,最大值等)。

+0

此建议也适用于Oracle,我怀疑,大多数其他RDBMS。 – APC 2009-11-23 18:12:36

+0

MySQL是我唯一知道的具有不同行为的设计,我很害怕:http://dev.mysql.com/doc/refman/5.0/en/group-by-hidden-columns.html – 2009-11-23 18:26:34

0

如果只想按Product_ID分组,请从GROUP BY子句中删除其他字段名称。如果您这样做,则还需要从SELECT列表中删除相同的字段名称(或将字段名称用一个聚合函数包围,例如MAX,MIN,SUM,,AVG)。如果仍然需要返回这些列,则可以将源表中的那些列的另一个JOIN作为嵌套子查询添加到查询中。

-1

由于您没有进行任何聚合组,因此仅仅是一种控制顺序的间接方式(并且它不可靠,因为这不是它的意思)。

如果您只想返回一个产品ID,则必须在其他字段上进行聚合,或者在where语句中添加一个子句,以便将数据库确切地告知数据库您要返回的单个记录。

+0

有使用SUM的字段 - 这是一个聚合函数 – Mark 2009-11-23 19:19:11

0

我认为这就是你想要的......如果不是,那么你必须更多地解释预期的输出。注意,在ms server 2005+中,执行CTE获取prodid总数然后执行到imagereport表的链接会更快。 - 或使用临时表。

SELECT getskusold.Product_ID, 
    max(imagereport.producttitle), 
    max(imagereport.URLimage), 
    max(imagereport.price), 
    max(imagereport.customfield2), 
    max(imagereport.season), 
    max(imagereport.active), 
    max(imagereport.discontinued), 
    max(imagereport.opttitle1), 
    max(imagereport.opttitle2), 
    max(imagereport.opttitle3), 

SUM(CASE WHEN processdate BETWEEN '2009-08-01 00:00:00.000' AND '2009-10-31 23:59:00.000' THEN getskusold.sprice ELSE 0 END) AS totalprice_date1, 
SUM(CASE WHEN processdate BETWEEN '2009-11-01 00:00:00.000' AND '2009-12-31 23:59:00.000' THEN getskusold.sprice ELSE 0 END) AS totalprice_date2, 
SUM(CASE WHEN processdate BETWEEN '2009-08-01 00:00:00.000' AND '2009-10-31 23:59:00.000' THEN getskusold.Qty ELSE 0 END) AS qtysold_date1, 
SUM(CASE WHEN processdate BETWEEN '2009-11-01 00:00:00.000' AND '2009-12-31 23:59:00.000' THEN getskusold.Qty ELSE 0 END) AS qtysold_date2 

FROM dbo.getskusold 
inner join imagereport 
on getskusold.product_id = imagereport.product_id 

GROUP BY getskusold.Product_ID 
0

您是“纵论”组中的所有字段by子句,如果你想ONL组; Y由产品ID,那么这是唯一的一个,应该是在GROUP BY子句。然后在选择需要的所有其他列是使用一些聚合函数输出(线最小,最大,平均等)

试试这个:

SELECT o.Product_ID, 
    Min(i.producttitle) MinTitle, Min(i.URLimage) MinImage, 
    Min(i.price) MinPrice, Min(i.customfield2) MinCustom, 
    Min(i.season) MinSeaason, Min(i.active) MinActive, 
    Min(i.discontinued) MinDiscontinued, 
    Min(i.opttitle1) MinOptTitle1, Min(i.opttitle2) MinOptTitle2, 
    Min(i.opttitle3) MinOptTitle3, 
     SUM(CASE WHEN processdate BETWEEN '2009-08-01 00:00:00.000' 
       AND '2009-10-31 23:59:00.000' 
      THEN o.sprice ELSE 0 END) AS totalprice_date1, 
     SUM(CASE WHEN processdate BETWEEN '2009-11-01 00:00:00.000' 
       AND '2009-12-31 23:59:00.000' 
      THEN o.sprice ELSE 0 END) AS totalprice_date2, 
     SUM(CASE WHEN processdate BETWEEN '2009-08-01 00:00:00.000' 
       AND '2009-10-31 23:59:00.000' 
      THEN o.Qty ELSE 0 END) AS qtysold_date1, 
     SUM(CASE WHEN processdate BETWEEN '2009-11-01 00:00:00.000' 
       AND '2009-12-31 23:59:00.000' 
      THEN o.Qty ELSE 0 END) AS qtysold_date2 
    FROM dbo.getskusold o 
     inner join imagereport i 
      on o.product_id = i.product_id 
    GROUP BY o.Product_ID 

,或者更好的,(因为它是更清晰),首先生成汇总结果集,然后再加入到图像表:

Select z.ProductId, i.producttitle, 
    i.URLimage, i.price, i.customfield2, 
    i.season, i.active, i.discontinued,  
    i.opttitle1, i.opttitle2, i.opttitle3, 
    z.totalprice_date1, z.qtysold_date1, 
    z.totalprice_date2, z.qtysold_date2 
From 
    (Select Product_ID ProductId, 
     Sum(CASE WHEN processdate BETWEEN '2009-08-01 00:00:00.000' 
       AND '2009-10-31 23:59:00.000' 
      THEN sprice ELSE 0 END) AS totalprice_date1, 
     Sum(CASE WHEN processdate BETWEEN '2009-11-01 00:00:00.000' 
       AND '2009-12-31 23:59:00.000' 
      THEN sprice ELSE 0 END) AS totalprice_date2, 
     Sum(CASE WHEN processdate BETWEEN '2009-08-01 00:00:00.000' 
       AND '2009-10-31 23:59:00.000' 
      THEN Qty ELSE 0 END) AS qtysold_date1, 
     Sum(CASE WHEN processdate BETWEEN '2009-11-01 00:00:00.000' 
       AND '2009-12-31 23:59:00.000' 
      THEN Qty ELSE 0 END) AS qtysold_date2 
    From dbo.getskusold 
    Group By Product_ID) Z 
     Join imagereport i 
      on i.product_id = Z.Productid 
0

从我的经验,是绑在一个特定的产品ID和查询不知道要返回的行很多行,但我有部分解决方案。

看看这个:

select (select top 1 [Name] from Product), SupplierID 
from Product 
group by SupplierID 

供应商ID是外键和有多个值。我要求sql引擎选择每个组的第一行。我以这种方式工作。如果要连接行,请检查this