私はおそらく数字テーブルを使用していたはずですが、これも機能します。
CREATE TABLE #myTable(ProjName VARCHAR(100), start_project DATETIME, finish_project DATETIME, verify_project DATETIME)
INSERT INTO #myTable SELECT 'proj1', '2017-01-01', '2017-04-15', '2017-04-15'
INSERT INTO #myTable SELECT 'proj2', '2017-01-02', '2017-01-11', '2017-01-11'
INSERT INTO #myTable SELECT 'proj3', '2017-06-06', '2017-06-06', '2017-06-06'
INSERT INTO #myTable SELECT 'proj4', '2017-03-01', '2017-08-15', '2017-08-15'
;with cte1 AS (
SELECT CASE
WHEN CAST(YEAR(t.start_project) AS VARCHAR) + CAST(MONTH(t.start_project) AS VARCHAR) <> CAST(YEAR(t.finish_project) AS VARCHAR) + CAST(MONTH(t.finish_project) AS VARCHAR)
THEN (DATEDIFF(DAY, start_project,EOMONTH(start_project, 0)) * 8) + 8
WHEN start_project = finish_project
THEN 8
ELSE (DATEDIFF(DAY, start_project,finish_project) * 8) + 8
END AS hours_this_month
, DATENAME(MONTH,start_project) AS month_name
, 0 AS month_level, start_project, finish_project, ProjName, verify_project
FROM #myTable t
UNION ALL
SELECT CASE
WHEN t.finish_project > EOMONTH(DATEADD(MONTH, t.month_level + 1, t.start_project))
AND (CAST(YEAR(t.start_project) AS VARCHAR) + CAST(MONTH(t.start_project) AS VARCHAR) <> CAST(YEAR(t.finish_project) AS VARCHAR) + CAST(MONTH(t.finish_project) AS VARCHAR))
THEN
(DATEDIFF(DAY, CAST(CAST(YEAR(DATEADD(MONTH, t.month_level + 1, t.start_project)) AS VARCHAR) + '-' +
CAST(MONTH(DATEADD(MONTH, t.month_level + 1, t.start_project)) AS VARCHAR) + '-01' AS DATETIME)
, EOMONTH(DATEADD(MONTH, t.month_level + 1, t.start_project))) * 8) + 8
ELSE
(DATEDIFF(DAY, CAST(CAST(YEAR(DATEADD(MONTH, t.month_level + 1, t.start_project)) AS VARCHAR) + '-' +
CAST(MONTH(DATEADD(MONTH, t.month_level + 1, t.start_project)) AS VARCHAR) + '-01' AS DATETIME)
, t.finish_project) * 8) + 8
END
, DATENAME(MONTH,DATEADD(MONTH, t.month_level + 1, t.start_project))
, t.month_level + 1
, t.start_project
, t.finish_project, t.ProjName, t.verify_project
FROM cte1 t INNER JOIN
#myTable myT ON myT.ProjName = t.ProjName
WHERE CAST(CAST(YEAR(DATEADD(MONTH, t.month_level + 1, t.start_project)) AS VARCHAR) + '-' +
CAST(MONTH(DATEADD(MONTH, t.month_level + 1, t.start_project)) AS VARCHAR) + '-01' AS DATETIME)
<= t.finish_project)
SELECT ProjName
, month_name
, hours_this_month
, start_project
, finish_project
, verify_project
, month_level
FROM cte1
ORDER BY ProjName, month_level ASC
出力...
proj1 January 248 2017-01-01 00:00:00.000 2017-04-15 00:00:00.000 2017-04-15 00:00:00.000 0
proj1 February 224 2017-01-01 00:00:00.000 2017-04-15 00:00:00.000 2017-04-15 00:00:00.000 1
proj1 March 248 2017-01-01 00:00:00.000 2017-04-15 00:00:00.000 2017-04-15 00:00:00.000 2
proj1 April 120 2017-01-01 00:00:00.000 2017-04-15 00:00:00.000 2017-04-15 00:00:00.000 3
proj2 January 80 2017-01-02 00:00:00.000 2017-01-11 00:00:00.000 2017-01-11 00:00:00.000 0
proj3 June 8 2017-06-06 00:00:00.000 2017-06-06 00:00:00.000 2017-06-06 00:00:00.000 0
proj4 March 248 2017-03-01 00:00:00.000 2017-08-15 00:00:00.000 2017-08-15 00:00:00.000 0
proj4 April 240 2017-03-01 00:00:00.000 2017-08-15 00:00:00.000 2017-08-15 00:00:00.000 1
proj4 May 248 2017-03-01 00:00:00.000 2017-08-15 00:00:00.000 2017-08-15 00:00:00.000 2
proj4 June 240 2017-03-01 00:00:00.000 2017-08-15 00:00:00.000 2017-08-15 00:00:00.000 3
proj4 July 248 2017-03-01 00:00:00.000 2017-08-15 00:00:00.000 2017-08-15 00:00:00.000 4
proj4 August 120 2017-03-01 00:00:00.000 2017-08-15 00:00:00.000 2017-08-15 00:00:00.000 5
は、MySQLやSQL Serverのですか?あなたのタグを編集することができますか? – bradbury9
@ bradbury9それはSQLサーバーです。私は反映するために私のタグを編集しました。 – user75514
私が考えている可能性のある唯一のアプローチは、カーソルを使用して各レコードを1つずつ調べ、関連するフィールドが月をオーバーラップしているかどうかを判断することですが、できるだけカーソルを避けようとしています。 – user75514