How do I get a count of events each day with SQL? - sql

I have a table that looks like this:
Timestamp Event User
================ ===== =====
1/1/2010 1:00 PM 100 John
1/1/2010 1:00 PM 103 Mark
1/2/2010 2:00 PM 100 John
1/2/2010 2:05 PM 100 Bill
1/2/2010 2:10 PM 103 Frank
I want to write a query that shows the events for each day and a count for those events. Something like:
Date Event EventCount
======== ===== ==========
1/1/2010 100 1
1/1/2010 103 1
1/2/2010 100 2
1/2/2010 103 1
The database is SQL Server Compact, so it doesn't support all the features of the full SQL Server. The query I have written so far is
SELECT DATEADD(dd, DATEDIFF(dd, 0, Timestamp), 0) as Date, Event, Count(Event) as EventCount
FROM Log
GROUP BY Timestamp, Event
This almost works, but EventCount is always 1. How can I get SQL Server to return the correct counts? All fields are mandatory.

Change your goup by to
GROUP BY DATEADD(dd, DATEDIFF(dd, 0, Timestamp), 0), Event

Related

DateDiff NIGHTMARE

seconfHere is an example:
ID Datetime1 datetime2 (Results needed)
1 1/1/2010 7:54 1/2/2010 6:54 23
1 1/1/2010 7:54 1/4/2010 6:54 48
1 1/1/2010 7:54 1/5/2010 6:54 24
2 1/5/2010 11:00 1/8/2010 11:00 72
3 1/30/2010 23:05 2/1/2010 22:05 47
notice ID 1 in the first row it did a normal datediff but in the second and third row I need it to use the startdate of datetime2 and enddate of datetime2 of thee same ID.
turnaround time column is what is the output column I need, I only tried normal datediff but it just calculates the difference between datetime1 and datetime2. my problem is that it can be many IDs with a value of 1, so I need the datediff to dynamically update the startdate if another enddate exist for the same ID.
Im' working in a RDBMS 'Microsoft SQL server'
the code i tried is as followed:
select
*
,datediff(hh,datetime1,datetime2) as 'Turnaround time'
from
my_table
order by datetime1 asc
i hope this clears it out a little bit.
thank you in advance
the answer was Lead and Lag functions URL below:
https://www.databasejournal.com/features/mssql/lead-and-lag-functions-in-sql-server-2012.html

Show data depending on the time of the day

I have a table that shows the amount of units produced by an employee. It also has the transaction time.
Is it possible to display data in such a way that when the current time is between 7 am to 3 pm it should only display the transaction that took place during that period of time and then when the current time is 3pm then it should only display the transactions between 3-11 pm.
sample data
units | name | TIME
-------------------------
10 | aa | 08:33:22
26 | bb | 10:33:22
36 | cc | 16:33:22
11 | dd | 18:33:22
Now if the current time is 13:00:00 i want all the transcations between 7am to 3pm which will be just the first 2. But when the time is 15:00:00 then it should automatically show all the transactions between 3pm - 11pm
You can use where:
where (datepart(hour, getdate()) between 7 and 14 and
datepart(hour, transactiondatetime) between 7 and 14
) or
(datepart(hour, getdate()) not between 7 and 14 and
datepart(hour, transactiondatetime) between 11 and 22
)

Split a row in sql server

In my DB, there are 2 tables ie RateCalendar & Blackout.
Ratecalendar stores daily, weekly, etc. rates between 2 dates for a Car Class. eg
From 10Jan to 27 May 2016, Daily rates are say £20,
weekly rates are £50 and so on.
Similarly, for other Dates range daily weekly rates are specified.
Suppose for 2 days (4May to 5May) I blackout my car ie car won't be available for a location. Now, I have to show the record as splitted ie from 10Jan to 3May, Cars will be available ie IsAvailable->True.
From 4th May to 5th May as Blackout (ie IsAvailable->False) and
from 6th till 29May again cars will be available.
All records will not split. Only those Cars whose details are present in blackout will split.
Moreover, depending on Blackout dates, splitting will be done. For eg. in blackout if there are two records for a car ie car is blacked out for say 10Jan to 12Jan And 4th May to 5th May, then, output will be like:
Car StartDate EndDate Available
Car1 10Jan2016 12:00 12Jan2016 1:00 N
Car1 12Jan2016 1:00 4May2016 9:00 Y
Car1 4May2016 9:00 5May2016 12:00 N
Car1 5May2016 12:00 27May2016 12:00 Y
Car2 10Jan2016 10:00 27May2016 12:00 Y
So, row can be splitted into 0 or 2 or multiple depending on Blackout dates for car.
What's the best way to do this?
Below is the layout of
1) RateCalendar Table(there are 2 more fields AgencyId,LocationId as shown in Blackout Table)
RateCalId RateGroupId CarClassId StartDate EndDate DailyRate
1 1 1 10Jan2016 10:00 26May2016 11:00 20
2 1 1 27May2016 11:00 28June2016 12:00 40
2) Blackout Table
BlackoutId AgencyId LocationId BeginDate EndDate
1 1 1 10Jan2016 12:00 12Jan2016 1:00
2 1 1 4May2016 9:00 5May2016 12:00
3) BlackoutCars
BlackoutId CarId
1 1
1 2
2 1
2 2
4) BlackoutRateGroup
BlackoutId RategroupId
1 1
1 0(0=>all)
2 3

GROUP BY several hours

I have a table where our product records its activity log. The product starts working at 23:00 every day and usually works one or two hours. This means that once a batch started at 23:00, it finishes about 1:00am next day.
Now, I need to take statistics on how many posts are registered per batch but cannot figure out a script that would allow me achiving this. So far I have following SQL code:
SELECT COUNT(*), DATEPART(DAY,registrationtime),DATEPART(HOUR,registrationtime)
FROM RegistrationMessageLogEntry
WHERE registrationtime > '2014-09-01 20:00'
GROUP BY DATEPART(DAY, registrationtime), DATEPART(HOUR,registrationtime)
ORDER BY DATEPART(DAY, registrationtime), DATEPART(HOUR,registrationtime)
which results in following
count day hour
....
1189 9 23
8611 10 0
2754 10 23
6462 11 0
1885 11 23
I.e. I want the number for 9th 23:00 grouped with the number for 10th 00:00, 10th 23:00 with 11th 00:00 and so on. How could I do it?
You can do it very easily. Use DATEADD to add an hour to the original registrationtime. If you do so, all the registrationtimes will be moved to the same day, and you can simply group by the day part.
You could also do it in a more complicated way using CASE WHEN, but it's overkill on the view of this easy solution.
I had to do something similar a few days ago. I had fixed timespans for work shifts to group by where one of them could start on one day at 10pm and end the next morning at 6am.
What I did was:
Define a "shift date", which was simply the day with zero timestamp when the shift started for every entry in the table. I was able to do so by checking whether the timestamp of the entry was between 0am and 6am. In that case I took only the date of this DATEADD(dd, -1, entryDate), which returned the previous day for all entries between 0am and 6am.
I also added an ID for the shift. 0 for the first one (6am to 2pm), 1 for the second one (2pm to 10pm) and 3 for the last one (10pm to 6am).
I was then able to group over the shift date and shift IDs.
Example:
Consider the following source entries:
Timestamp SomeData
=============================
2014-09-01 06:01:00 5
2014-09-01 14:01:00 6
2014-09-02 02:00:00 7
Step one extended the table as follows:
Timestamp SomeData ShiftDay
====================================================
2014-09-01 06:01:00 5 2014-09-01 00:00:00
2014-09-01 14:01:00 6 2014-09-01 00:00:00
2014-09-02 02:00:00 7 2014-09-01 00:00:00
Step two extended the table as follows:
Timestamp SomeData ShiftDay ShiftID
==============================================================
2014-09-01 06:01:00 5 2014-09-01 00:00:00 0
2014-09-01 14:01:00 6 2014-09-01 00:00:00 1
2014-09-02 02:00:00 7 2014-09-01 00:00:00 2
If you add one hour to registrationtime, you will be able to group by the date part:
GROUP BY
CAST(DATEADD(HOUR, 1, registrationtime) AS date)
If the starting hour must be reflected accurately in the output (as 9, 23, 10, 23 rather than as 10, 0, 11, 0), you could obtain it as MIN(registrationtime) in the SELECT clause:
SELECT
count = COUNT(*),
day = DATEPART(DAY, MIN(registrationtime)),
hour = DATEPART(HOUR, MIN(registrationtime))
Finally, in case you are not aware, you can reference columns by their aliases in ORDER BY:
ORDER BY
day,
hour
just so that you do not have to repeat the expressions.
The below query will give you what you are expecting..
;WITH CTE AS
(
SELECT COUNT(*) Count, DATEPART(DAY,registrationtime) Day,DATEPART(HOUR,registrationtime) Hour,
RANK() over (partition by DATEPART(HOUR,registrationtime) order by DATEPART(DAY,registrationtime),DATEPART(HOUR,registrationtime)) Batch_ID
FROM RegistrationMessageLogEntry
WHERE registrationtime > '2014-09-01 20:00'
GROUP BY DATEPART(DAY, registrationtime), DATEPART(HOUR,registrationtime)
)
SELECT SUM(COUNT) Count,Batch_ID
FROM CTE
GROUP BY Batch_ID
ORDER BY Batch_ID
You can write a CASE statement as below
CASE WHEN DATEPART(HOUR,registrationtime) = 23
THEN DATEPART(DAY,registrationtime)+1
END,
CASE WHEN DATEPART(HOUR,registrationtime) = 23
THEN 0
END

For Each Loop in SQL Server using Cursor

I have a table with 4 cols.
HouseNo, Date, Time and Temp.
I have managed to obtain the different HouseNos in a separate table. Now i want to insert all the dates for all the house nos.
Sample Data from table. There are like a few million rows like this.
HouseNo Date Time Temp
102 1/1/2010 10:00 67
102 2/1/2010 10:00 73
102 3/1/2010 10:00 75
103 1/1/2010 10:00 69
103 2/1/2010 10:00 63
104 1/1/2010 10:00 71
104 2/1/2010 10:00 12
Expected Output is
table 1
102 1/1/2010
102 2/1/2010
102 3/1/2010
table 2
103 1/1/2010
103 2/1/2010
table 3
104 1/1/2010
104 2/1/2010
Then i want to be able to loop through each row in the tables derieved to perform some operation on the temperature field.
If you have one ON/OFF pair per day and the OFF is always before the ON, this gets you the duration.
SELECT
HouseNo,
Date,
DATEDIFF(s,
MIN(CASE WHEN Relay='OFF' THEN Time ELSE NULL END),
MIN(CASE WHEN Relay='ON' THEN Time ELSE NULL END)
) As OffDuration
FROM YourTable
GROUP BY HouseNo, Date
But any normal real life dataset will have multiple ON/OFF pairs. Can you give more detail?
something like this ?
CREATE TABLE new_table
AS (SELECT * FROM old_table);
you can also put some WHERE part and SELECT