我正在尝试执行相当复杂的SQL查询来生成报告。这是库存和会计系统使用的数据库。
基本上我需要使用以下列生成报告
报告中需要使用以下表格:
基本上,查询需要以下列方式开始:
1.从发票
中选择所有发票
2.从Reseller.Name获取经销商名称(使用Invoice.CustomerID加入Reseller.ID)
3.从Job表中获取关联的作业ID(使用Invoice.ID加入Job.InvoiceID)
4.从JobStockItems获取发票的每个组成部分(在Job.ID上加入JobStockItem.JobID)
5.从Stock中获取作业中的库存项目(在Stock.ID上加入JobStockItems.StockId)并查看类别(Stock.Category1)是硬件还是耗材
6.如果库存项目是硬件或消耗品,请使用JobStockItem(JobStockItem.PriceExTax)中的销售价格并将其添加到经销商购买月份的总额中
月份和年份来自发票日期(Invoice.InvoiceDate)。
现在我可以通过执行一堆查询和处理自己来生成这个结果,每个都用于上述步骤,但它最终会变慢,我确信那里必须有一个查询可以将所有这些要求包起来并在一个中完成吗?
我还没有尝试过查询,说实话,我不知道从哪里开始 - 它比我过去所做的任何事都复杂得多。
我只使用Management Studio,而不是使用Reporting Services,Crystal Reports或其他任何东西。我的目标是在工作时将输出转储为HTML。
提前谢谢你们。
答案 0 :(得分: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
我假设零售商有一个名为Name的列,您也想要返回,可以随意将其更改为ID或其他您想要返回的内容。
编辑:修复查询以删除重复项
答案 1 :(得分: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中的金额相乘......
答案 2 :(得分: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