Click here to Skip to main content
15,891,136 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I have a report (above table) where I count number of PfLocationIds on given day by PfLocationId. StartTime and EndTime are user inputs. I want build this report using stored procedure. How can I do this in SQL Server?

Image description here[^]

What I have tried:

used to pivot, but can't grop by overlap date time range
Posted
Updated 29-Dec-16 21:18pm
v3
Comments
Maciej Los 29-Dec-16 1:47am    
So, show us the method you create a pivot table!

1 solution

The best way to achieve that is to use CTE (Common Table Expressions)[^]. Please, study below example:

--i'm using temporary table as source table
DECLARE @src TABLE(RentId INT IDENTITY(1,1), PfLocationId INT, StartTime DATE, EndTime DATE);
INSERT INTO @src 
VALUES(1, '2016-01-07', '2016-01-13'),
(1, '2016-01-05', '2016-01-10'),
(2, '2016-01-08', '2016-01-08'),
(2, '2016-01-11', '2016-01-12'),
(3, '2016-01-10', '2016-01-13')

--define range of dates to generate report
DECLARE @startdate DATE = '2016-01-07'
DECLARE @enddate DATE = DATEADD(DD, 7, @startdate)

--create temporary table to store the result of CTE
IF OBJECT_ID('#tmp', 'U') IS NOT NULL DROP TABLE #tmp

CREATE TABLE #tmp(CurrentDate DATE, PfLocationId INT, NoOfRents INT)

--use recursive query to grab data into temporary table
;WITH DateRange AS
(
	--initial data
	--'Occurence' field with default value of 1 will be used for further calculations 
	SELECT @startdate AS CurrentDate, T.RentId, T.PfLocationId, T.StartTime, T.EndTime, 1 AS Occurence
	FROM @src AS T
	WHERE StartTime>=@startdate OR EndTime<=@enddate 
	--recursive part: increase CurrentDate 
	UNION ALL
	SELECT DATEADD(DD, 1, CurrentDate) AS CurrentDate, RentId, PfLocationId, StartTime, EndTime, 1 AS Occurence
	FROM DateRange
	WHERE DATEADD(DD, 1, CurrentDate) <= EndTime 
)
INSERT INTO #tmp (CurrentDate, PfLocationId, NoOfRents)
SELECT DR.CurrentDate, DR.PfLocationId, SUM(DR.Occurence) AS NoOfRents
FROM DateRange AS DR
WHERE DR.CurrentDate>=DR.StartTime
GROUP BY DR.CurrentDate, DR.PfLocationId

--declare string variable to get all dates
DECLARE @dates VARCHAR(2000) = ''

SET @dates = STUFF((
    SELECT DISTINCT '], [' + CONVERT(VARCHAR(10), CurrentDate) 
    FROM #tmp 
	--ORDER BY CurrentDate 
    FOR XML PATH('')
    ), 1, 2, '') + ']';

--declare variable for pivot data
DECLARE @sql VARCHAR(MAX) = ''
SET @sql = 'SELECT PfLocationId, ' + @dates +
' FROM #tmp AS DT ' +
' PIVOT(MAX(NoOfRents) FOR CurrentDate IN(' + @dates + ')) AS PT'

--execute pivot query
EXEC(@sql)

--drop tempoaray table
DROP TABLE #tmp 


For further details, please see:
WITH common_table_expression (Transact-SQL)[^]
Using Common Table Expressions[^]
 
Share this answer
 
Comments
Tiền Bối 30-Dec-16 20:32pm    
Thanks you very much @Maciej. This solution is almost perfect, but there is one small problem is how to define EndTime as a parameter, the current fixed EndTime when I try to change the parameters. Looking forward to more support from your fear

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900