Pull a DATEDIFF between Rows with Distinct value and WHERE Clause - sql

I'm trying to generate a DATEDIFF to calculate SLA adherence, but the table info I need to perform the DATEDIFF is replicated in rows (instead of a start time column, end time column).
As such, I need to set a WHERE statement for the same column, using 2 different StatusIds to DATEDIFF those two timestamps.
For example,
PackageId | StatusId | rowDateModified
--------------------------------------
1 1 2019-06-01 00:41
1 2 2019-06-01 01:30
Ideally, I need to be able to calculate how long it took between package creation (StatusId = 1) and package completion (StatusId = 2) for an infinite number of rows, where the PackageId is Distinct.

You can use conditional aggregation:
select packageid,
datediff(day,
max(case when statusid = 1 then rowdatemodified end),
max(case when statusid = 2 then rowdatemodified end)
)
from t
group by packageid

Related

Count rows within each group when condition is satisfied Sql Server

I have at table which looks like below:
ID Date IsFull
1 2020-01-05 0
1 2020-02-05 0
1 2020-02-25 1
1 2020-03-01 1
1 2020-03-20 1
I want to display how many months for ID = 1
have sum(isfull)/count(*) > .6 in a given month (More than 60% of the times in that month isfull = 1)
So the final output should
ID HowManyMonths
1 1 --------(Only month 3----2 out 2 cases)
If the question changes to sum(isfull)/count(*) > .4
then the final output should be
ID HowManyMonths
1 2 --------(Month 2 and Month 3)
Thanks!!
You can do this with two levels of aggregation:
select id, count(*) howManyMonths
from (
select id
from mytable
group by id, year(date), month(date)
having avg(1.0 * isFull) > 0.6
) t
group by id
The subquery aggregates by id, year and month, and uses a having clause to filter on groups that meet the success rate (avg() comes handy for this). The outer query counts how many month passed the target rate for each id.

trying to get Statistics for data based on another parameter

Struggling again on statistics on data based on other sets of data.
I have a list of customers. like the following:
CustomerID Value Date
1 3 01/01/2017
2 2 01/02/2017
3 1 01/02/2017
1 5 01/04/2017
1 6 01/04/2017
2 1 01/04/2017
2 2 01/04/2017
I want to get an average for a date range for Customer 1 on the days where customer 2 also has values. Does anyone have any thoughts?
example
Select avg(value)
from Table where customerid=1
and (customer 2 values are not blank)
and date between '01/01/2017' and '01/31/2017'
I am using SQL Server Express 2012.
Another Option
Select AvgValue = Avg(Value+0.0) -- Remove +0.0 if you want an INT
From YourTable
Where CustomerID = 1
and Date in (Select Distinct Date from YourTable Where CustomerID=2)
Returns
AvgValue
5.500000
You can select the dates using exists or in and then calculate the average:
select avg(value)
from datatbl t
where customerid = 1 and
exists (select 1 from datatbl t2 where t2.customerId = 2 and t2.date = t.date);
If you want the average per date, then include group by date.

SQL return count between occurence based on date range

I'm trying to return a count of ID occurrences based on a date range and group by between two (occurrence) values.
The data is simple like this:
Date | ID
The result I am trying to accomplish looks like this:
DateRange | Occurrence-Count-1to2-Times | Occurrence-Count-3to5-Times | Occurrence-Count-6to10-Times | Occurrence-Count-Over10-Times
The Occurrence Count is how many times an ID shows between the two values. e.g. between 1 and 2 times (according to the date range specified).
Thanks!
You can do two levels of aggregation:
select date,
sum(case when cnt <= 2 then 1 else 0 end) then times_1_2,
sum(case when cnt > 2 and cnt <= 5 then 1 else 0 end) then times_3_5,
. . .
from (select date, id, count(*) as cnt
from t
group by date, id
) di
group by date;
I'm not sure what you mean by "date range", but you can define the range in the subquery and use that for aggregation in both the subquery and the outer query.

Count of distinct values per day, excluding reoccuring until value changes

I'm really struggling with how to explain this so I'll try and give you the format of the table below, and the desired outcome.
I have a table which contains a uniqueID, date, userID and result. I'm trying to count the number of results that are 'Correct' per day, but I only want to count unique occurances based on the userID column. I then want to exclude any furhter occurances of 'Correct' for that particular userID, until the result for the userID changes to 'Success'.
UID Date UserID Result
1 01/01/2014 5 Correct
2 01/01/2014 5 Correct
3 02/01/2014 4 Correct
4 03/01/2014 4 Correct
5 03/01/2014 5 Incorrect
6 03/01/2014 4 Incorrect
7 05/01/2014 5 Correct
8 07/01/2014 4 Correct
9 08/01/2014 5 Success
10 08/01/2014 4 Success
Based on the above data, I'd expect to see the below:
Date Correct Success
01/01/2014 1 0
02/01/2014 1 0
03/01/2014 0 0
05/01/2014 0 0
07/01/2014 0 0
08/01/2014 0 2
Can anyone help? I'm using SQL Server 2008
Use count(distinct) with case:
select date,
count(distinct case when result = 'Correct' then UserId end) as Correct,
count(distinct case when result = 'Success' then UserId end) as Success
from data d
group by date
order by date;
EDIT:
The above counts correct on all occurrences. If you only want the first one to be counted:
select date,
count(case when result = 'Correct' and seqnum = 1 then UserId end) as Correct,
count(case when result = 'Success' and seqnum = 1 then UserId end) as Success
from (select d.*,
row_number() over (partition by UserId, result order by Uid) as seqnum
from data d
) d;
In this case, the distinct is unnecessary.

Count number of occurrences for each unique value [duplicate]

This question already has answers here:
Count the occurrences of DISTINCT values
(4 answers)
Closed 5 years ago.
Basically I have a table similar to this:
time.....activities.....length
13:00........3.............1
13:15........2.............2
13:00........3.............2
13:30........1.............1
13:45........2.............3
13:15........5.............1
13:45........1.............3
13:15........3.............1
13:45........3.............2
13:45........1.............1
13:15........3.............3
A couple of notes:
Activities can be between 1 and 5
Length can be between 1 and 3
The query should return:
time........count
13:00.........2
13:15.........2
13:30.........0
13:45.........1
Basically for each unique time I want a count of the number of rows where the activities value is 3.
So then I can say:
At 13:00 there were X amount of activity 3s.
At 13:45 there were Y amount of activity 3s.
Then I want a count for activity 1s,2s,4s and 5s. so I can plot the distribution for each unique time.
Yes, you can use GROUP BY:
SELECT time,
activities,
COUNT(*)
FROM table
GROUP BY time, activities;
select time, coalesce(count(case when activities = 3 then 1 end), 0) as count
from MyTable
group by time
SQL Fiddle Example
Output:
| TIME | COUNT |
-----------------
| 13:00 | 2 |
| 13:15 | 2 |
| 13:30 | 0 |
| 13:45 | 1 |
If you want to count all the activities in one query, you can do:
select time,
coalesce(count(case when activities = 1 then 1 end), 0) as count1,
coalesce(count(case when activities = 2 then 1 end), 0) as count2,
coalesce(count(case when activities = 3 then 1 end), 0) as count3,
coalesce(count(case when activities = 4 then 1 end), 0) as count4,
coalesce(count(case when activities = 5 then 1 end), 0) as count5
from MyTable
group by time
The advantage of this over grouping by activities, is that it will return a count of 0 even if there are no activites of that type for that time segment.
Of course, this will not return rows for time segments with no activities of any type. If you need that, you'll need to use a left join with table that lists all the possible time segments.
If i am understanding your question, would this work? (you will have to replace with your actual column and table names)
SELECT time_col, COUNT(time_col) As Count
FROM time_table
GROUP BY time_col
WHERE activity_col = 3
You should change the query to:
SELECT time_col, COUNT(time_col) As Count
FROM time_table
WHERE activity_col = 3
GROUP BY time_col
This vl works correctly.