SQL选择复杂逻辑
我有一个复杂的场景,我会尽力解释 我在ProjectPhases表中有一个名为“Phase”的列,其中包含关于项目阶段的描述。然后,有一个名为DailyReport的表包含诸如描述、QTY1、QTY2、PHASEID(ProjectPhases表中的外键)等字段 现在,前端的用户将为一周中的每一天创建每日报告记录。现在,我编写查询来总结包含ProjectPhases数据和daily report数据的日报SQL选择复杂逻辑,sql,sql-server,sql-server-2008,group-by,sum,Sql,Sql Server,Sql Server 2008,Group By,Sum,我有一个复杂的场景,我会尽力解释 我在ProjectPhases表中有一个名为“Phase”的列,其中包含关于项目阶段的描述。然后,有一个名为DailyReport的表包含诸如描述、QTY1、QTY2、PHASEID(ProjectPhases表中的外键)等字段 现在,前端的用户将为一周中的每一天创建每日报告记录。现在,我编写查询来总结包含ProjectPhases数据和daily report数据的日报 select P.projectname ,PP.Description a
select P.projectname ,PP.Description as Phase,DD.description, DD.QTYSunday,DD.QTYSMonday,DD.QTYTues,
from
Document_DailyReport DD LEFT OUTER JOIN
ProjectPhases PP on PP.Id=DD.PhaseId LEFT OUTER JOIN
Projects P on P.Id=DD.ProjectId
查询的输出采用以下格式
ProjectName Phase Description QTYSunday QTYMonday QtyTues
Project1 Phase 1 Qty-SUNDAy 10
Project1 Phase 1 Qty-Monday 10
Project1 Phase 1 Qty-Monday 10
ProjectName Phase QTYSunday QTYMonday QtyTues
Project1 Phase 1 10 10 10
现在我希望输出的格式如下
ProjectName Phase Description QTYSunday QTYMonday QtyTues
Project1 Phase 1 Qty-SUNDAy 10
Project1 Phase 1 Qty-Monday 10
Project1 Phase 1 Qty-Monday 10
ProjectName Phase QTYSunday QTYMonday QtyTues
Project1 Phase 1 10 10 10
我想把某一特定阶段的每日报告的所有记录放在一行中,就像上面所说的那样
谢谢
编辑:
我的完整问题如下
SELECT P.projectname ,
PP.Description AS Phase,
DD.Description,
DD.DocNumber,
(SELECT CompanyName
FROM Companies
WHERE Id=dbo.GetCompanyIdByUser(DD.InsertedBy)) AS CreatedBy,
DD.ReportDate,
(SELECT sum(quantity)+sum(cast(field9 AS INT))
FROM Document_DailyReportOnSite
WHERE DailyReportId=DD.Id
AND ClassificationId=1
AND DATEDIFF(DAY,reportdate,DATEADD(dd, -(DATEPART(dw, (@Date)-1)), @Date)) =0) AS StaffQuantitySun,
(SELECT sum(quantity)+sum(cast(field9 AS INT))
FROM Document_DailyReportOnSite
WHERE DailyReportId=DD.Id
AND ClassificationId=1
AND DATEDIFF(DAY,reportdate,DATEADD(dd, 1-(DATEPART(dw, (@Date)-1)), @Date)) =0) AS StaffQuantityMon,
(SELECT sum(quantity)+sum(cast(field9 AS INT))
FROM Document_DailyReportOnSite
WHERE DailyReportId=DD.Id
AND ClassificationId=1
AND DATEDIFF(DAY,reportdate,DATEADD(dd, 2-(DATEPART(dw, (@Date)-1)), @Date)) =0) AS StaffQuantityTues,
(SELECT sum(quantity)+sum(cast(field9 AS INT))
FROM Document_DailyReportOnSite
WHERE DailyReportId=DD.Id
AND ClassificationId=1
AND DATEDIFF(DAY,reportdate,DATEADD(dd, 3-(DATEPART(dw, (@Date)-1)), @Date)) =0) AS StaffQuantityWed,
(SELECT sum(quantity)+sum(cast(field9 AS INT))
FROM Document_DailyReportOnSite
WHERE DailyReportId=DD.Id
AND ClassificationId=1
AND DATEDIFF(DAY,reportdate,DATEADD(dd, 4-(DATEPART(dw, (@Date)-1)), @Date)) =0) AS StaffQuantityThur,
(SELECT sum(quantity)+sum(cast(field9 AS INT))
FROM Document_DailyReportOnSite
WHERE DailyReportId=DD.Id
AND ClassificationId=1
AND DATEDIFF(DAY,reportdate,DATEADD(dd, 5-(DATEPART(dw, (@Date)-1)), @Date)) =0) AS StaffQuantityFri,
(SELECT sum(quantity)+sum(cast(field9 AS INT))
FROM Document_DailyReportOnSite
WHERE DailyReportId=DD.Id
AND ClassificationId=1
AND DATEDIFF(DAY,reportdate,DATEADD(dd, 6-(DATEPART(dw, (@Date)-1)), @Date)) =0) AS StaffQuantitySat ,
FROM Document_DailyReport DD
LEFT OUTER JOIN ProjectPhases PP ON PP.Id=DD.PhaseId
LEFT OUTER JOIN Projects P ON P.Id=DD.ProjectId
WHERE DD.ReportDate BETWEEN DATEADD(dd, -(DATEPART(dw,@Date)-1), @Date) AND DATEADD(dd, 6-(DATEPART(dw, @Date)-1), @Date)
输出
projectname Phase description CreatedBy 0StaffQuantityMon StaffQuantityTues StaffQuantityWed StaffQuantityThur
Bollywood Park (MCC-ARCO) Bollywood Theatre Main Contractor Package Daily Report as on 16-Jun-2014 ARCO Contracting 22 NULL NULL NULL
Bollywood Park (MCC-ARCO) Bollywood Theatre Main Contractor Package Daily Report as om 17-Jun-2014 ARCO Contracting NULL 23 NULl NULL
Bollywood Park (MCC-ARCO) Bollywood Theatre Main Contractor Package Daily Report as on 18.06.2014 ARCO Contracting NULL NULL NULL 23
使用
分组依据
功能
试试这个:
SELECT P.projectname, PP.Description AS Phase,
SUM(DD.QTYSunday) AS QTYSunday,
SUM(DD.QTYSMonday) AS QTYSMonday,
SUM(DD.QTYTues) AS QTYTues
FROM Projects P
INNER JOIN Document_DailyReport DD ON P.Id = DD.ProjectId
LEFT OUTER JOIN ProjectPhases PP ON PP.Id = DD.PhaseId
GROUP BY P.projectname, PP.Description;
我可以看到你的描述包括列名,如“数量星期日”
您可以使用描述字段上的轴来返回所需的结果集。有大量文档可供您使用。您可以尝试以下方法:
SELECT ProjectName, Phase, SUM(StaffQuantitySun) AS StaffQuantitySun, SUM(StaffQuantityMon) AS StaffQuantityMon, SUM(StaffQuantityTues) AS StaffQuantityTues, SUM(StaffQuantityWed) AS StaffQuantityWed,
SUM(StaffQuantityThur) AS StaffQuantityThur, SUM(StaffQuantityFri) AS StaffQuantityFri, SUM(StaffQuantitySat) AS StaffQuantitySat
(
select P.projectname ,PP.Description as Phase,DD.Description,DD.DocNumber,
(Select CompanyName from Companies where Id=dbo.GetCompanyIdByUser(DD.InsertedBy)) As CreatedBy,DD.ReportDate,
(select sum(quantity)+sum(cast(field9 as INT)) from Document_DailyReportOnSite where DailyReportId=DD.Id and ClassificationId=1 and DATEDIFF(day,reportdate,DATEADD(dd, -(DATEPART(dw, (@Date)-1)), @Date)) =0) as StaffQuantitySun,
(select sum(quantity)+sum(cast(field9 as INT)) from Document_DailyReportOnSite where DailyReportId=DD.Id and ClassificationId=1 and DATEDIFF(day,reportdate,DATEADD(dd, 1-(DATEPART(dw, (@Date)-1)), @Date)) =0) as StaffQuantityMon,
(select sum(quantity)+sum(cast(field9 as INT)) from Document_DailyReportOnSite where DailyReportId=DD.Id and ClassificationId=1 and DATEDIFF(day,reportdate,DATEADD(dd, 2-(DATEPART(dw, (@Date)-1)), @Date)) =0) as StaffQuantityTues,
(select sum(quantity)+sum(cast(field9 as INT)) from Document_DailyReportOnSite where DailyReportId=DD.Id and ClassificationId=1 and DATEDIFF(day,reportdate,DATEADD(dd, 3-(DATEPART(dw, (@Date)-1)), @Date)) =0) as StaffQuantityWed,
(select sum(quantity)+sum(cast(field9 as INT)) from Document_DailyReportOnSite where DailyReportId=DD.Id and ClassificationId=1 and DATEDIFF(day,reportdate,DATEADD(dd, 4-(DATEPART(dw, (@Date)-1)), @Date)) =0) as StaffQuantityThur,
(select sum(quantity)+sum(cast(field9 as INT)) from Document_DailyReportOnSite where DailyReportId=DD.Id and ClassificationId=1 and DATEDIFF(day,reportdate,DATEADD(dd, 5-(DATEPART(dw, (@Date)-1)), @Date)) =0) as StaffQuantityFri,
(select sum(quantity)+sum(cast(field9 as INT)) from Document_DailyReportOnSite where DailyReportId=DD.Id and ClassificationId=1 and DATEDIFF(day,reportdate,DATEADD(dd, 6-(DATEPART(dw, (@Date)-1)), @Date)) =0) as StaffQuantitySat ,
from
Document_DailyReport DD LEFT OUTER JOIN
ProjectPhases PP on PP.Id=DD.PhaseId LEFT OUTER JOIN
Projects P on P.Id=DD.ProjectId
Where DD.ReportDate between DATEADD(dd, -(DATEPART(dw,@Date)-1), @Date) and DATEADD(dd, 6-(DATEPART(dw, @Date)-1), @Date)
) DerivedTable
GROUP BY ProjectName, Phase
基本上,我已经将您的查询嵌入到一个派生表中,然后按项目名称和阶段进行分组,然后将您希望的所有列汇总到一行中。我认为这不会产生预期的结果,我可能是错的,尽管QTYSunday,QTYMonday都是子查询,我把它们作为直接字段,以便使我的问题不那么复杂。由于它们是子查询,我无法对它们应用聚合函数。这称为
PIVOT
查询,SQL Server实际上有一些函数可以帮助实现这一点。可能的重复我不确定是否可以使用PIVOT完成。我的输出中的值不是常量,无法将其转换为PIVOT,这只是一个示例。描述将不是固定不变的。请在我的问题的末尾找到原始输出。很酷,不用担心,伙计。注意,考虑到子查询中的日期数学,我希望这会像糖浆一样缓慢地覆盖任何实际大小的数据集。根据实际日期进行分组(可能是使用PIVOT
的一部分)可能会产生更好的结果。只是不要包含任何不属于最终输出的列。