2016-06-09 42 views
0

我正在尝试为承包商创建一个就业时间表。我需要输出一个包含日期列的表格,并具有可变数量薪酬的灵活性。在时间表场景中将行转换为列

的工资水平是在一个叫做“价格”表,这些都需要成为输出表的列:

RATEID PROJECTID RATENAME RATEOFPAY 
1   1   Normal  1000 
2   1   Double  2000 
3   1   Special 2500 
4   2   Flatrate 1000 
5   3   Rateone 1000 
6   3   Rate2  1500 

我已经有一个生成范围之间的日期函数:

SELECT IndividualDate FROM DateRange('03-01-16', '03-30-16') as DATESINRANGE 

This outputs

IndividualDate 
2016-03-01 00:00:00.000 
2016-03-02 00:00:00.000 
thru 
2016-03-30 00:00:00.000 

我有第三张表,其中包含有关何时这些对比构建函数工作,速度和小时数(他们可能不会每天都工作):

dateworked projectid rateid  hoursworked 
2016-03-02 1   2   5 
2016-03-02 1   3   2 

我想是到输出,显示了一个月的专案编号的每一天= 1像这样的表:

Dates  Normal  Double Special 
2016-03-01 0   0   0 
2016-03-02 0   5   2 
2016-03-03 0   0   0 
etc... 

我已经看过PIVOT的例子,但不知道它们是否适用于这种情况下,因为这些例子使用了聚合。我真的很感谢帮助。

回答

0

我会尝试以下解决方案:

DECLARE @ProjectID INT = 1, @FromDt DATE = '2016-03-01', @ToDt DATE = '2016-03-31' 

DECLARE @RateColumns NVARCHAR(MAX) = N'', @SqlStatement NVARCHAR(MAXW); 

SELECT @RateColumns = @RateColumns + N', ' + QUOTENAME(RateName) 
FROM dbo.PayRates a 
WHERE a.ProjectID = @ProjectID 

IF @@ROWCOUNT = 0 
BEGIN 
    RAISERROR('Internal error: there is no rates for current project', 16, 1) 
END 

SET @RateColumns = STUFF(@RateColumns, 1, 2, N'') 

SET @SqlStatement = N' 
SELECT b.* 
FROM (
    SELECT IndividualDate, HoursWorked, RateName 
    FROM dbo.DateRange(@FromDt, @ToDt) f 
    LEFT JOIN dbo.ThirdTable tt ON ff.IndividualDate = tt.DateWorked 
    AND tt.ProjectID = @ProjectID 
    LEFT JOIN dbo.PayRates pr ON tt.RateID = pr.RateID 
    AND pr.ProjectID = tt.ProjectID -- Is it necessary ? 
) a 
PIVOT(SUM(HoursWorked) FOR RateName IN (' + @RateColumns + N') b' 

EXEC sp_executesql 
    @SqlStatement, 
    N'@ProjectID INT, @FromDt DATE, @ToDt DATE', 
    @ProjectID, @FromDt, @ToDt 
+0

我想我的SQL技能上有很多今天提出从上面的学习。我的时间表正在工作,谢谢。 –

0

看看这是否会让你开始。这肯定不是最理想的解决方案,但希望它可以帮助

IF OBJECT_ID('tempdb..#Rates') IS NOT NULL 
DROP TABLE #Rates 
IF OBJECT_ID('tempdb..#RatePivot') IS NOT NULL 
DROP TABLE #RatePivot 
IF OBJECT_ID('tempdb..#DatesWorked') IS NOT NULL 
DROP TABLE #DatesWorked 

CREATE TABLE #Rates (RATEID INT, PROJECTID INT, RATENAME VARCHAR(24), RATEOFPAY MONEY) 

INSERT INTO #Rates(RATEID,PROJECTID,RATENAME,RATEOFPAY)VALUES 
(1,1,'Normal',1000), 
(2,1,'Double',2000), 
(3,1,'Special',2500), 
(4,2,'Flatrate',1000), 
(5,3,'Rateone',1000), 
(6,3,'Rate2',1500) 

create table #DatesWorked(dateworked datetime,projectid int, rateid int, hoursworked int) 
insert into #DatesWorked (dateworked,projectid,rateid,hoursworked) values 
('2016-03-02',1,2,5), 
('2016-03-02',1,3,2) 

select * into #RatePivot from 
(select PROJECTID, RATEID, RATENAME, RATEOFPAY from #Rates) as r 
pivot 
(max(RATEOFPAY) for RATENAME in ([Normal],[Double],[Special],[Flatrate],[Rateone],[Rate2])) as p 

select * from #RatePivot 

select 
    d.dateworked, 
    count(r.Normal) as Normal, 
    count(r.[Double]) as [Double], 
    count(r.Special) as Special, 
    count(r.Flatrate) as Flatrate, 
    count(r.Rateone) as Rateone, 
    count(r.Rate2) as Rate2 
from 
    #DatesWorked d 
    inner join #RatePivot r on r.RATEID = d.rateid and r.PROJECTID = d.projectid 
where d.projectid = 1 
group by d.dateworked