SSRS Timesheet like form - sql-server

I have this record in my sql server..
RecId RefJobTicket TimeStart TimeEnd VerByStart VerByEnd Cargo PreTrip Transit LoadingUnloading WaitForAdvice MealBreak Breakdown PostTrip Refuel Remarks
2 1 12:00 1:00 NULL NULL NULL 0 0 0 0 0 0 NULL 0 NULL
49 1 3:00 4:00 NULL NULL NULL 0 0 0 0 0 0 NULL 0 NULL
50 1 5:00 8:00 NULL NULL NULL 0 0 0 0 0 0 NULL 0 NULL
In my SSRS REPORT.. I want to put it in a Pre Defined form that look like below according to the available records i have in the sql server:
time start time end Refuel Trip Meal Break
12:01AM 1:00AM 0 Null Null
1:01AM 2:00AM
2:01AM 3:00AM
3:01AM 4:00AM Null 0 Null
4:01AM 5:00AM
5:01AM 6:00AM Null Null 0
6:01AM 7:00AM Null Null 0
7:01AM 8:00AM Null Null 0
8:01AM 9:00AM
9:01AM 10:00AM
10:01AM 11:00AM
11:01AM 12:00PM
12:01PM 1:00PM
1:01PM 2:00PM
2:01PM 3:00PM
3:01PM 4:00PM
4:01PM 5:00PM
5:01PM 6:00PM
6:01PM 7:00PM
7:01PM 8:00PM
8:01PM 9:00PM
9:01PM 10:00PM
10:01PM 11:00PM
11:01PM 12:00AM
Can i do this in ssrs r2?? Can any one help me?

Yes, You can do it. you need to take care of following points:
Step1:
your query should return all the times (12:01AM to 12:00AM). You can do a cross join of following query on your main query. Note that, Report can not generate those times that are not coming from your sql query.
;with Minute_Cycle
as
(
select cast('12:01AM' as time) Mint
Union ALL
Select DATEADD(HOUR,1,cast(Mint as time)) Mint from Minute_Cycle
where convert(varchar(15),cast(Mint as time),100)<>'11:01PM'
)
Select convert(varchar(15),Mint,100) as time_start, convert(varchar(15),DATEADD(MINUTE,59,Mint),100) time_End from Minute_Cycle
Step2
Place a table and design your report as per your choice.

Related

SQL Server query to add a column based on value of another column

I have a query that select a list of DATETIME values and I would like to add to this selection a column that is populated based on the value of DATETIME column
Example for every value that is between 19:00 and 23:00 the value in the new column should be 2
Value DATETIME 2022-04-05 22:25:39.083
Value NEW COLUMN 2
My goal is to only select this new value, I cannot make modifications to the exiting table
It is something that can be managed by SQL Server?
Thanks
I don't know how to create new columns and if is possible to use like IF statement in SQL
first let's discuss how to provide example data. One of the better options is to define an object we can easily replicate, and then populate it with some data. In this case the datetime values don't matter, they just need to exist. Something like this will get us there:
DECLARE #dates TABLE (DateID INT IDENTITY, DateTime DATETIME)
WHILE (SELECT COUNT(*) FROM #dates) < 100
BEGIN
INSERT INTO #dates (DateTime)
SELECT DATEADD(HOUR,(ROUND(((96 - 1 -1) * RAND(CAST(NEWID() AS VARBINARY)) + 1), 0) - 1),CURRENT_TIMESTAMP)
END
All we're doing here is generating a random datetime in the next 96 hours and inserting it into our table variable.
Now on to your problem.
This is easily resolved by using the TIME data type. You can cast any DATETIME to a TIME. Then, you can simply compare it to a valid time range, using a case expression:
SELECT *, CASE WHEN CAST(DateTime AS TIME) BETWEEN '19:00' AND '23:00' THEN 2 ELSE 0 END AS NewColumn
FROM #dates
ORDER BY DateTime
DateID DateTime NewColumn
-----------------------------------------
81 2022-11-07 17:13:39.813 0
78 2022-11-07 18:13:39.813 0
22 2022-11-07 19:13:39.810 2
87 2022-11-07 19:13:39.813 2
95 2022-11-07 19:13:39.813 2
2 2022-11-08 01:13:39.807 0
98 2022-11-08 01:13:39.813 0
12 2022-11-08 04:13:39.807 0
...
19 2022-11-08 17:13:39.810 0
34 2022-11-08 19:13:39.810 2
56 2022-11-08 19:13:39.810 2
39 2022-11-08 19:13:39.810 2
66 2022-11-08 22:13:39.810 2
96 2022-11-08 22:13:39.813 2
90 2022-11-08 22:13:39.813 2
50 2022-11-08 23:13:39.810 0
5 2022-11-09 00:13:39.807 0
...
46 2022-11-11 09:13:39.810 0
6 2022-11-11 10:13:39.807 0
51 2022-11-11 11:13:39.810 0

How to display data by rolling day for three months when data has datestamp for state change by column

I have data formatted like this:
ID
Date Created
Date Ready to Start
Date In Progress
Date Dev Complete
Date Test Complete
Date Accepted
1
2021-11-01 12:01:15
2021-11-02 14:01:15
2021-11-04 05:01:15
2021-11-04 12:01:15
2021-11-05 12:01:15
2021-11-06 12:01:15
2
2021-11-01 12:01:45
NULL
2021-11-03 12:01:15
NULL
NULL
2021-11-05 12:01:15
3
2021-11-03 11:11:05
2021-11-04 12:01:15
NULL
NULL
NULL
NULL
4
2021-11-05 19:31:45
2021-11-05 12:01:15
2021-11-06 12:01:15
NULL
NULL
NULL
5
2021-11-04 13:21:25
NULL
NULL
NULL
NULL
NULL
and I need it formatted like this:
Date
Created
Ready to Start
In Progress
Dev Complete
Test Complete
Accepted
2021-11-01
2
0
0
0
0
0
2021-11-02
0
1
0
0
0
0
2021-11-03
1
0
1
0
0
0
2021-11-04
0
1
1
1
0
0
2021-11-05
1
1
0
0
1
1
2021-11-06
0
0
1
0
0
1
with rolling dates going back 3 months from current date.
I am unsure of how to start this... Would I union a recursive table creating the rolling calendar to the existing data or would I do a series of custom selects for counts and then group by date?
Try something like this:
DECLARE #Today date = GetDate();
DECLARE #MinDate date = DateAdd(month, -3, #Today);
DECLARE #DayCount int = 1 + DateDiff(day, #MinDate, #Today);
WITH cteNumbers As
(
/* Use a tally-table here if you have one: */
SELECT TOP (#DayCount)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) As N
FROM
sys.all_columns
),
cteCalendar As
(
SELECT
DateAdd(day, N, #MinDate) As [Date],
DateAdd(day, N + 1, #MinDate) As NextDay
FROM
cteNumbers
)
SELECT
C.[Date],
(
SELECT Count(1)
FROM YourTable As T
WHERE T.[Date Created] >= C.[Date]
And T.[Date Created] < C.NextDay
) As [Created],
(
SELECT Count(1)
FROM YourTable As T
WHERE T.[Date Ready to Start] >= C.[Date]
And T.[Date Ready to Start] < C.NextDay
) As [Ready to Start],
...
FROM
cteCalendar As C
;

T-SQL how to calculate datediff from previous or next row on log?

I use MS SSMS 2008 R2 to extract data from our company management software, which registers our employee actions and schedules. The table has and ID field, which is unique to each entry. job is the activity the user is performing. user is the user ID. start_time and duration are exactly that. Then there is a "type" where 0 is login (the user logs into the job) and 1 is available time (while performing a job the user may be available or not). "reason" is the reason why the user has become unavailable (break, coffee, lunch, training, etc). Type 0 entries have no reason so reason is always null.
I need to extract the unavailable times by reason and all I'm being able to achieve is to do a DATEADD of duration to start_time in order to get end_time and then use Excel to manually calculate the times for each row.
The SQL table looks like this:
id job user start_time duration type reason
4436812 3 758 05-06-2015 09:00 125670 0 NULL
4436814 3 758 05-06-2015 09:00 6970 1 1004
4436944 3 758 05-06-2015 09:14 39280 1 1004
4437119 3 758 05-06-2015 10:20 0 1 1002
4437172 3 758 05-06-2015 10:35 18470 1 1004
4437312 3 758 05-06-2015 11:09 3960 1 1004
4437350 3 758 05-06-2015 11:16 0 1 1006
4437360 3 758 05-06-2015 11:19 30080 1 1004
4437638 3 758 05-06-2015 12:13 6730 1 1004
4437695 3 758 05-06-2015 12:24 0 1 1007
4438227 3 758 05-06-2015 13:43 NULL 0 NULL
4438228 3 758 05-06-2015 13:43 NULL 1 NULL
(job = 3 and user = 758)
This is the query I made:
select CONVERT(date,start_time) Data, a.job, a.user, convert(varchar(15),convert(datetime,a.start_time),108) StartTime, a.duration duracao,
convert(varchar(15),convert(datetime,DATEADD(second,a.duration/10,a.start_time)),108) EndTime, a.type, a.reason
from schedule_log a
where a.job = 3
and a.user = 758
and CONVERT(date,start_time) = '20150605'
order by a.start_time, a.type
Which translates to:
Date job user LogTime Avail NotAvail
2015-06-05 3 758 04:44:01 04:10:23 00:33:38
So, for each reason, I have to do a DATEDIFF from end time (start+duration) to either the next type 1 start_time or the previous type 0 end time, which ever happened first (the user may become unavailable and then logoff).
How do I do this?
ps: duration is in tenths of second.
Ok, here is my updated suggestion. It is broken into three steps for clarity, but the temp tables are unnecessary - they could become subqueries.
Step 1: Calculate the end time for each period of activity, excluding logins.
Step 2: Join each row to the row that occurred immediately after it, to get the unavailable time following each reason. Note: some of your timestamps do not line up properly, possibly as a result of storing duration in seconds but timestamps only to the minute.
Step 3: Total the unavailable time, and subtract from the duration of the login to get the available time.
Step 4: Total the unavailable time by reason.
SELECT *
,dateadd(s, duration / 10, start_time) AS Endtime
,row_number() OVER (
PARTITION BY job ,[user] ORDER BY start_time, [type]
) AS RN
INTO #temp2
FROM MyTable
WHERE [type] = 1
SELECT a.[user]
,a.job
,a.reason
,a.start_time
,a.type
,a.duration / 10 AS AvailableSeconds
,datediff(s, a.Endtime, b.start_time) AS UnavailableSeconds
INTO #temp3
FROM #temp2 a
LEFT JOIN #temp2 b
ON a.[user] = b.[user]
AND a.job = b.job
AND a.RN = b.RN - 1
SELECT cast(a.start_time AS DATE) AS [Date]
,a.job
,a.[user]
,b.duration / 10 AS LogTime
,b.duration / 10 - sum(UnavailableSeconds) AS Avail
,sum(UnavailableSeconds) AS NotAvail
FROM #temp3 a
LEFT JOIN MyTable b
ON a.job = b.job
AND a.[user] = b.[user]
AND b.[type] = 0
AND b.duration IS NOT NULL
GROUP BY cast(a.start_time AS DATE)
,a.job
,a.[user]
,b.duration
SELECT cast(a.start_time AS DATE) AS [Date]
,a.job
,a.[user]
,a.reason
,sum(UnavailableSeconds) AS NotAvail
FROM #temp3 a
where reason is not null
GROUP BY cast(a.start_time AS DATE)
,a.job
,a.[user]
,a.reason

SQL query sorted by year, counting values per year

I have this SQL query, which gives me the numbers of orders within a date range, and that is OK:
SELECT CardName, ItemNumber, COUNT(*) AS antal, year(date) as aarstal, SUM(Numbers) AS total, sum(case when year(date)=2012 then 1 else 0 end) as newtest
FROM tblOrders
WHERE (Publisher = 3) AND (Date > '01-01-2012 00:00:00') AND (Date < '30-09-2014 23:59:59') AND (Status = 3) and ItemNumber!=9130 and ItemNumber!=9180 and ItemNumber!=9170 and ItemNumber!=9190
GROUP BY ItemNumber, CardName, year(date)
This gives me ie
CompanyA 0 76 2012 10900 76
CompanyA 0 42 2013 6300 0
CompanyB 0 1 2012 100 1
CompanyB 0 7 2013 1100 0
CompanyC 0 1 2014 300 0
CompanyD 0 7 2014 700 0
CompanyE 0 2 2012 300 2
CompanyE 0 1 2013 200 0
From this, I can see that CompanyA bought 10900 units in 2012, from a total of 76 orders that year, and in 2013, they bought 6300 units. For sales reasons, we would like (or need) this output as
CompanyA 0 76 2012 10900 42 2013 6300
CompanyB 0 1 2012 100 7 2013 1100
CompanyC 0 1 2014 300 0 2013 0
CompanyD 0 7 2014 700 0 2013 0
CompanyE 0 2 2012 300 1 2013 200
So you could see if a customer is going up or down in sales. I've tried various things, but I don't know if there is any possibility to have the Numbers column SUM'ed up per year in a query like this, any suggestions?
PS: The
sum(case when year(date)=2012 then 1 else 0 end) as newtest
was just for a test, I tried something like SUM(Numbers case...) but that was not accepted!
EDIT: I just made a demo in SQL Fiddle, just to give a better understanding of my problem:
http://sqlfiddle.com/#!3/072a1/5
In there, you can see that my customer A has bought a total of 300 in 2012 (on 2 orders), 700 in 2013 (on 2 orders), and finally 200 in 2014 (on 1 order). The pivot examples I've found only counts the number of orders, and not the value of my Numbers - could somebody edit the SQL Fiddle, making that one work, then I'm sure I could learn and adapt the solution into my "real" database?
/Tommy

SQL query issue No data is showing

here is my result set but when i am doing query on the result set then no data is coming but i am not being able to understand what is the wrong in my query.
call Start Caller direction Is_Internal continuation call duration party1name
------------------ ------------ --------- ----------- ------------ ------------------ -----------------
1/15/2014 8:47 346241552 I 0 0 0:00:18 VM Kanaal 1
1/15/2014 9:56 252621028 I 0 0 0:00:17 Kanaal 1
1/15/2014 9:58 252621028 I 0 0 0:00:17 Kanaal 1
1/15/2014 9:01 252621028 I 0 1 0:00:08 Kanaal 1
1/15/2014 9:01 252621028 I 0 0 0:01:57 Coen
1/15/2014 9:06 302 O 0 0 0:01:53 Coen
1/15/2014 9:07 306 O 0 0 0:01:33 koos de Bruijn
1/15/2014 9:11 644686793 I 0 0 0:00:08 VM Kanaal 1
1/15/2014 9:11 644686793 I 0 0 0:01:46 Coen
1/15/2014 9:27 306 O 0 0 0:00:43 koos de Bruijn
1/15/2014 9:25 302 O 0 0 0:06:46 Coen
1/15/2014 9:46 455426194 I 0 1 0:00:07 VM Kanaal 1
1/15/2014 9:46 455426194 I 0 0 0:00:50 Coen
1/15/2014 9:57 725716251 I 0 1 0:00:10 VM Kanaal 1
1/15/2014 10:00 0 I O 1 0:00:00 Voicemail
my query is here
SELECT Convert(varchar,[call Start],101) Date,[Caller] [Phone No], Count(*) [Total Incomming calls] FROM tridip
where direction='I' and
CAST([call Start] AS datetime) >= CONVERT(datetime,'09:00:00') and
CAST([call Start] AS datetime) <= CONVERT(datetime,'17:30:00')
AND Is_Internal=0 and continuation=0 AND
CONVERT(datetime,CAST([call duration] AS DATETIME),108) <> CAST('00:00:00' AS DATETIME)
and party1name not in ('Voice Mail') and party1name not like 'VM %'
and party1name not like 'Line%'
group by [Caller],Convert(varchar,[call Start],101)
just tell me what is wrong my query. it should show date & phone number and count may be 1 or more than 1. please guide me what to alter.
at the second row there is phone no 252621028 which is repeated and it's count should be greater than 1.
thanks
UPDATE
i figured out the problem and rectified sql as follow
SELECT [Caller] [Phone No], Count(*) [Total Incomming calls] FROM tridip
where direction='I' and
CONVERT(VARCHAR,[call Start],108) >= '09:00:00' and
CONVERT(VARCHAR,[call Start],108) <= '17:30:00'
AND Is_Internal=0 and continuation=0 AND
[call duration] <> '00:00:00'
and party1name not in ('Voice Mail') and party1name not like 'VM %'
and party1name not like 'Line%' and [Caller]>0
group by [Caller]
You are not getting results most probably because of this condition -
CAST([call Start] AS datetime) <= CONVERT(datetime,'17:30:00')
Reason -
Try this -
SELECT CONVERT(datetime,'17:30:00')
The result is - 1900-01-01 17:30:00.000
I believe none of your records have [call start] time less than this and hence no results.
Are your trying to get all the records between 2 times ?
As has been previously mentioned, you are getting a DateTime with the value of 1900-01-01 09:00, which is obviously lower than any of your dates.
You can also use the DATEPART function of SQL Server to compare dates and times easier:
where direction='I'
and DATEPART(hour, CAST([call Start] AS datetime)) >= 9
and DATEPART(hour, CAST([call Start] AS datetime)) <= 17
(You will need to modify this slightly to work for being before 17:30, but it gives you the general idea).

Resources