2011-06-14 173 views
1

我正在嘗試執行相當複雜的SQL查詢來生成報表。這是庫存和會計系統使用的數據庫。複雜SQL查詢幫助

基本上我需要製成具有以下列的報告

  • 月/年(組結果按月/年)
  • 經銷商(爲了結果由經銷商與月/年組)
  • 總銷售額 - 銷售 - 硬件
  • 總銷售額 - 銷售 - 耗材

下表需要在報告中使用:

  • 發票
  • 經銷商
  • 工作
  • JobStockItem
  • 股票

本質上查詢需要作爲開始:
1 。從發票中選擇所有發票
2.獲取經銷商不適用我從Reseller.Name(使用Invoice.CustomerID加入Reseller.ID)
3.從作業表中獲取關聯的作業ID(使用Invoice.ID加入Job.InvoiceID)
4.從發票的每個組件JobStockItems(在Job.ID上加入JobStockItem.JobID)
5.從股票中獲取股票項目(在Stock.ID上加入JobStockItems.StockId),並查看該類別(Stock.Category1)是硬件還是耗材
6.如果庫存產品的硬件或消耗品,使用在JobStockItem(JobStockItem.PriceExTax)的銷售價格,並將其添加對總的經銷商購買

月份和年份都來自於一個月INVOIC e日期(Invoice.InvoiceDate)。

現在我可以通過執行一系列查詢和處理自己來完成這個結果,每一步都可以執行上述步驟,但最終會變得很慢,而且我確定必須有一個查詢那可以把所有這些要求都包裝起來並且在一箇中完成呢?

我還沒有試圖做這個查詢,但說實話,我不知道從哪裏開始 - 這比我過去做的任何事情都要複雜得多。

我只是使用Management Studio,沒有使用Reporting Services,Crystal Reports或任何東西。我的目標是在輸出時將輸出轉儲爲HTML。

感謝提前堆。

+0

我沒有看到你從得到的月/年的信息 - 你似乎並不能夠加入任何「銷售」表之類的東西.. .. – 2011-06-14 04:41:37

+0

您使用什麼工具生成報告? Crystal Reports,Microsoft Access,SQL Reporting ...等 – RThomas 2011-06-14 04:42:10

+0

到目前爲止,您的嘗試是什麼?你試過去了嗎? – Bohemian 2011-06-14 04:42:47

回答

4

它認爲如果你離開加入JobStockItems表兩次(一次爲硬件,一次爲消費品),你可以管理所有在一個查詢。最終的查詢將看起來像這樣(沒有我的編輯了,現在,這樣的道歉任何錯別字)

SELECT DATEPART(m, Invoice.InvoiceDate) month, 
     DATEPART(yy, Invoice.InvoiceDate) year, 
     Reseller.Name, 
     SUM(jobstockitems_hardware.Price) sales_hardware, 
     SUM(jobstockitems_consumables.Price) sales_consumables, 
FROM Invoice 
INNER JOIN Reseller 
ON Invoice.CustomerID = Reseller.ID 
INNER JOIN Job 
ON Invoice.ID = Job.InvoiceID 
LEFT JOIN (SELECT JobID, SUM(PriceExTax) Price 
      FROM JobStockItems 
      INNER JOIN Stock 
      ON JobStockItems.StockID = Stock.StockID 
      AND Stock.Category1 = 'Hardware' 
      GROUP BY JobID) jobstockitems_hardware 
ON Job.ID = jobstockitems_hardware.JobID 
LEFT JOIN (SELECT JobID, SUM(PriceExTax) Price 
      FROM JobStockItems 
      INNER JOIN Stock 
      ON JobStockItems.StockID = Stock.StockID 
      AND Stock.Category1 = 'Consumables' 
      GROUP BY JobID) jobstockitems_consumables 
ON Job.ID = jobstockitems_consumables.JobID 
GROUP BY DATEPART(m, Invoice.Date), 
     DATEPART(yy, Invoice.Date), 
     Reseller.Name 
ORDER BY DATEPART(yy, Invoice.Date) ASC, 
     DATEPART(m, Invoice.Date) ASC, 
     Reseller.Name ASC 

我假設零售商要返回以及一列稱爲名稱,隨時將其改爲ID或其他任何您希望返回的內容。

編輯:固定的查詢來刪除重複

+0

您需要在子查詢中總結硬件和耗材表(或與條件和的和 - SUM(CASE WHERE Category1 =?...)),否則結果將關閉('PriceExTax'將會是如果經銷商有多個'stock_consumables'行,那麼這兩個類別都會重複。 – 2011-06-14 04:55:50

+0

你完全正確。我編輯了查詢來反映這一點。 – dpmattingly 2011-06-14 05:05:37

+0

哇,榮譽 - 出色地工作。對不起,我的遲到的回覆,一直沒有透露。乾杯@dp ... – Sam 2011-06-15 08:22:13

0

晴要樞結果。所以,你可以簡單地一起加入您的數據,讓PIVOT做類別的選擇和總結:

select * 
from (
     select Year = datepart(year, i.InvoiceDate), 
       Month = datepart(month, i.InvoiceDate), 
       ResellerName = r.name, 
       StockCategory = s.Category1, 
       jsi.PriceExTax 
     from Invoice i 
     inner join Reseller r 
      on r.ID = i.CustomerID 
     inner join Job j 
      on j.InvoiceID = i.ID 
     inner join JobStockItem jsi 
      on jsi.JobID = j.ID 
     inner join Stock s 
      on s.ID = jsi.StockID 
     ) d 
pivot (sum(PriceExTax) for StockCategory in (Hardware, Consumables)) p 
order by Year, Month, ResellerName; 

到底你需要在內部查詢某些情況下(例如在i.InvoiceDate之間... )。 您可能需要將PriceExTax與JobStockItem中的數量相乘......

0

DPMattingley已經生成了一個很好的查詢,但有一個限制 - 如果時間段沒有結果,它將不會顯示任何行。在這裏的具體例子中,這可能不太可能發生,但是在發生這種情況時,發現報告隱藏了零結果月份令人討厭!

我的標準解決方案涉及從numbers table的月份,這迫使所有時間段出現。使用DPMattingley的查詢爲出發點 -

select 
    mths.month, 
    mths.year, 
    d.Name, 
    d.sales_hardware, 
    d.sales_consumables 
from 
    /*All the in-range months on which to report*/ 
    (select 
     datepart(m,dateadd(m,number,minDate)) month, 
     datepart(yy,dateadd(m,number,minDate)) year 
    from 
     numbers n 
      inner join (select min(invoice.invoicedate) as minDate from invoice) m 
       on n.number between 0 and datediff(m,minDate,getdate())) mths 

     left join 
      /*Data for each month*/ 
      (SELECT DATEPART(m, Invoice.InvoiceDate) month, 
        DATEPART(yy, Invoice.InvoiceDate) year, 
        Reseller.Name, 
        SUM(jobstockitems_hardware.Price) sales_hardware, 
        SUM(jobstockitems_consumables.Price) sales_consumables 
      FROM 
       Invoice 
        INNER JOIN Reseller 
         ON Invoice.CustomerID = Reseller.ID 
        INNER JOIN Job 
         ON Invoice.ID = Job.InvoiceID 
        LEFT JOIN (SELECT JobID, SUM(PriceExTax) Price 
           FROM JobStockItems 
           INNER JOIN Stock 
           ON JobStockItems.StockID = Stock.StockID 
           AND Stock.Category1 = 'Hardware' 
           GROUP BY JobID) jobstockitems_hardware 
         ON Job.ID = jobstockitems_hardware.JobID 
        LEFT JOIN (SELECT JobID, SUM(PriceExTax) Price 
           FROM JobStockItems 
           INNER JOIN Stock 
           ON JobStockItems.StockID = Stock.StockID 
           AND Stock.Category1 = 'Consumables' 
           GROUP BY JobID) jobstockitems_consumables 
         ON Job.ID = jobstockitems_consumables.JobID 
      GROUP BY DATEPART(m, Invoice.Date), 
         DATEPART(yy, Invoice.Date), 
         Reseller.Name) d 
       on mths.month=d.month 
       and mths.year=d.year 

ORDER BY mths.month ASC, 
      mths.year ASC, 
      Reseller.Name ASC