2009-11-23 95 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