[英]Complex SQL Query Help
我正在尝试执行相当复杂的 SQL 查询来生成报告。 这是库存和会计系统使用的数据库。
基本上我需要生成一个包含以下列的报告
报告中需要使用以下表格:
本质上,查询需要以以下方式开始:
1. Select 所有发票来自 Invoice
2. 从 Reseller.Name 获取经销商名称(在 Reseller.ID 上加入 Invoice.CustomerID)
3. 从 Job 表中获取关联的 Job ID(Job.InvoiceID 与 Invoice.ID 结合)
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 或其他任何东西。 我的目标是在我工作时将 output 转储到 HTML。
提前致谢。
它认为,如果您两次将左联接加入 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
我假设 Retailer 有一个名为 Name 的列,您也想返回它,请随时将其更改为 ID 或您希望返回的任何其他内容。
编辑:修复查询以删除重复项
部分你想要 PIVOT 你的结果。 因此,您可以简单地将数据连接在一起,让 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 中的金额相乘...
DPMattingley 产生了一个很好的查询,但有一个限制 - 如果一个时间段没有结果,它根本不会显示一行。 在此处的特定示例中,这很可能不太可能发生,但是在确实发生的情况下,发现报告隐藏了零结果月份是很烦人的!
我对此的标准解决方案包括从数字表中获取月份,这会强制显示所有时间段。 使用 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.