2016-04-05 4 views
0

私のTSQLクエリをcteにすることに問題があります。私はそれがその候補だと確信しています。私は他のクエリでcteを使用しましたが、これは複数のソースからデータを取得する必要があり、それが私に悲しみを引き起こしています。ここで私は働くこと持っているものです:醜いT SQLクエリをCTEに変換する

declare @projid int   = 0 
declare @proj varchar  = (select projectid from Projects where projectid = @projid) 
declare @maxid int   = (select max(projectid) from Projects) 
declare @projsize bigint = (select projectsizeexpitem from Projects where projectid = @projid) 
declare @numofdays int  = (select DATEDIFF(DAY, MIN(starttime), GETDATE()) from transactions where projectid = @projid) 
declare @dailyrate bigint = (select (SUM(transactionitemsmigrated)/@numofdays) from Transactions where projectid = @projid) 
declare @complete bigint = (select SUM(transactionitemsmigrated) from transactions where projectid = @projid) 
declare @daysremaining int = (select (CAST(GETDATE() AS int) + ((@[email protected])/@dailyrate))) 

WHILE @projid < @maxid 

BEGIN 
    IF @projid IN (select projectid from projects) 
    BEGIN 
     set @proj   = (select projectname from Projects where projectid = @projid) 
     set @maxid   = (select max(projectid) from Projects) 
     set @projsize  = (select projectsizeexpitem from Projects where projectid = @projid) 
     set @numofdays  = (select DATEDIFF(DAY, MIN(starttime), GETDATE()) from transactions where projectid = @projid) 
     set @dailyrate  = (select (SUM(transactionitemsmigrated)/@numofdays) from Transactions where projectid = @projid) 
     set @complete  = (select SUM(transactionitemsmigrated) from transactions where projectid = @projid) 
     set @daysremaining = (select (CAST(GETDATE() AS int) + ((@[email protected])/@dailyrate))) 
     select 
      [Project]   = (select projectname from projects where projectid = @projid), 
      [TotalItems]  = @projsize, 
      [DaysActive]  = @numofdays, 
      [DailyRate]   = @dailyrate, 
      [TotalComplete]  = @complete, 
      [ItemsRemaining] = @projsize - @complete, 
      [DaysRemaining]  = ((@[email protected])/@dailyrate), 
      [CompDate]   = CAST(CAST(@daysremaining AS datetime) AS date) 
      SET @projid = @projid + 1 
    END 
    ELSE 
    BEGIN 
     SET @projid = @projid + 1 
    END 
END 

この1の問題は、それが別の結果テーブルとしてSELECT文の各反復を返すことです。集約のためにそれらをすべて一緒に持っていたいと思います。私が試したことは次のとおりです。

declare @projid int   = 0 
declare @proj varchar  = (select projectid from Projects where projectid = @projid) 
declare @maxid int   = (select max(projectid) from Projects) 
declare @projsize bigint = (select projectsizeexpitem from Projects where projectid = @projid) 
declare @numofdays int  = (select DATEDIFF(DAY, MIN(starttime), GETDATE()) from transactions where projectid = @projid) 
declare @dailyrate bigint = (select (SUM(transactionitemsmigrated)/@numofdays) from Transactions where projectid = @projid) 
declare @complete bigint = (select SUM(transactionitemsmigrated) from transactions where projectid = @projid) 
declare @daysremaining int = (select (CAST(GETDATE() AS int) + ((@[email protected])/@dailyrate))) 

;WITH cte AS (
    select 
     [ID]    = 1, 
     [Project]   = (select projectname from projects where projectid = @projid), 
     [TotalItems]  = @projsize, 
     [DaysActive]  = @numofdays, 
     [DailyRate]   = @dailyrate, 
     [TotalComplete]  = @complete, 
     [ItemsRemaining] = @projsize - @complete, 
     [DaysRemaining]  = ((@[email protected])/@dailyrate), 
     [CompDate]   = CAST(CAST(@daysremaining AS datetime) AS date) 
    UNION ALL 
    select 
     [ID] + 1, 
     [Project]  = (select projectname from projects where projectid = @projid), 
     [TotalItems] = @projsize, 
     [DaysActive] = @numofdays, 
     [DailyRate]  = @dailyrate, 
     [TotalComplete] = @complete, 
     [ItemsRemaining]= @projsize - @complete, 
     [DaysRemaining] = ((@[email protected])/@dailyrate), 
     [CompDate]  = CAST(CAST(@daysremaining AS datetime) AS date) 
    from cte 
    where [ID] < @maxid 
) 

select * 
from cte 
where @projid <= @maxid 
OPTION (MAXRECURSION 100) 

EDIT:入手しました。ここで私が使ったことがあります。 @ Amit-Sukraliaに感謝してくれた彼のコメントは私を解決に導いた!

SELECT 
    [Project]   = projectName, 
    [TotalItems]  = projectsizeexpitem, 
    [DaysActive]  = (select DATEDIFF(DAY, MIN(starttime), GETDATE()) from transactions where projectid = p.projectid), 
    [DailyRate]   = (select (SUM(transactionitemsmigrated)/(DATEDIFF(DAY, MIN(starttime), GETDATE()))) from Transactions where projectid = p.projectid), 
    [TotalComplete]  = (select SUM(transactionitemsmigrated) from transactions where projectid = p.projectid), 
    [ItemsRemaining] = projectsizeexpitem - (select SUM(transactionitemsmigrated) from transactions where projectid = p.projectid), 
    [ExpectedCompDate] = CAST((GETDATE() + ((p.projectsizeexpitem-(select SUM(transactionitemsmigrated) from transactions where projectid = p.projectid))/ 
          (select (SUM(transactionitemsmigrated)/(DATEDIFF(DAY, MIN(starttime), GETDATE()))) from Transactions where projectid = p.projectid))) as int) - CAST(GETDATE() as int) 
FROM Projects p 

答えて

1

以下のように試すことができます。それはCTEを必要としません:

SELECT 
    ROW_NUMBER() OVER (PARTITION BY projectid) AS ID, 
    projectName AS [Project], 
    (select max(projectid) from Projects) AS MaxId, 
    projectsizeexpitem AS [TotalItems], 
    (select DATEDIFF(DAY, MIN(starttime), GETDATE()) from transactions where projectid = p.projectid) AS [DaysActive], 
    (select (SUM(transactionitemsmigrated)/(DATEDIFF(DAY, MIN(starttime), GETDATE()))) from Transactions where projectid = p.projectid) AS [DailyRate], 
    (select SUM(transactionitemsmigrated) from transactions where projectid = p.projectid) AS [TotalComplete], 
    projectsizeexpitem - (select SUM(transactionitemsmigrated) from transactions where projectid = p.projectid) AS [ItemsRemaining], 
    (select (CAST(GETDATE() AS int) + ((projectsizeexpitem - (select SUM(transactionitemsmigrated) from transactions where projectid = p.projectid))/ 
             (select (SUM(transactionitemsmigrated)/(DATEDIFF(DAY, MIN(starttime), GETDATE()))) from Transactions where projectid = p.projectid)))) AS [DaysRemaining] 
from Projects p 
+0

私はそれをしましたが、読みやすさの問題でどのように見えたのかはわかりませんでした。私は他のチームメンバーがそれを読むことができるようにしたい。しかし、あなたのセットアップはトリックをします...ほぼ。私は実際に[ID]と[MaxId]を削除して、必要なものを手に入れることができます。しかし、[DaysRemaining]は、42495、42654などのような数値を返すことになります。どういうわけかそこに数学的誤差がありますか?彼らはほとんど50-200の間でなければなりません。 –

+0

入手しました。ご協力いただきありがとうございます!元の投稿にソリューションを追加しました。 –