Excel - Count first time contributors - countif

What I would like to do is count the amount of first time contributors by month. So for January, there were 3 people that contributed in January for the first time, 1 in February, and 1 in March.
I wasn't sure how to write a countifs function (maybe a different function?) that would exclude those who contributed in previous months. Thanks.
Employee| January| February| March| Year Totals
PR | 3 | 0 | 0 | 3
RK | 2 | 1 | 1 | 4
JG | 0 | 1 | 2 | 3
ST | 1 | 0 | 4 | 5
DM | 0 | 0 | 2 | 2
1st time| 3 | 1 | 1

If Employee is in Sheet1 A1 and the sheet is copied into Sheet2 with the data replaced from B2 to suit with:
=--AND(SUM(Sheet1!$A2:B2)>0,SUM(Sheet1!$A2:A2)=0)
then in Sheet1 in ColumnB and copied across to suit:
=SUM(Sheet2!B:B)

Related

Sql check a value in column is greater than number of rows

i am building a web app where customer can book a service from a business(vendor). but first vendor need to add
what services he provide, where he able to deliver those services, and from which time (start time) to which time(end time) how many users is available
so i am confusing that suppose a customer book a service for some particular time and when another customer book a service from that vendor we need to calculate is the number of users available
in this time period is greater than count of already booking (which are not completed yet) in that particular time
i have these three table
users = (for both customer & vendors)
id | name | address | role_id
1 | Customer | some address | 1
2 | Vendor | Some Address | 2
3 | Another Customer | Some address | 1
4 | Another Vendor | address | 2
vendor_available_time = (only for vendor)
id | date_start_time | date_end_time | no_of_users |vendor_id
1 | 2019-10-16 00:00:00 | 2019-19-16 23:59:59 | 3 | 2
1 | 2019-10-16 09:00:00 | 2019-19-16 17:00:00 | 1 | 4
1 | 2019-10-17 00:00:00 | 2019-19-17 23:59:59 | 3 | 2
1 | 2019-10-17 09:00:00 | 2019-19-17 17:00:00 | 2 | 4
bookings = (for both)
id | booking_status | booking_datetime | customer_id | vendor_id
1 | job started | 2019-10-16 10:00:00 | 1 | 2
1 | completed | 2019-10-15 10:00:00 | 1 | 2
1 | accepted | 2019-10-16 09:00:00 | 3 | 2
1 | work in progress | 2019-10-16 09:00:00 | 3 | 2
please help me with a query
where i can get all vendors whose no_of_users is greater than count(bookings) where booking_datetime >= date_start_time and booking_datetime < date_end_time and booking_status is not in ['completed', 'rejected', 'cancelled']
Any suggestion will be really appreciated can i get those result from one query, should i use multiple queries or should i change my database structure
The output i want is just a user_ids whose are available for that time period and whose no of users is greater than already count of bookings for that time
Is this what you want?
Select b.vendor_id from
bookings b join vendor_available_time v on b.vendor_id=v.id
where b.booking_datetime >= v.date_start_time and
b.booking_datetime < v.date_end_time
and b.booking_status not in ['completed', 'rejected', 'cancelled']
group by b.vendor_id having count(distinct b.id) <=count(b.customer_id)

subtract 2 DB rows from each other for each unique partner_ID? MYSQL

I have a MYSQL table where I need to get to subtract values from 2 different rows.
This is my DB table:
Tablename: ext_partnertotals
| Partner_ID | Partnername | Month | Year | Total |
|------------|-------------|-------|------|-------|
| 1 | Partner 1 | 1 | 2018 | 10 |
| 1 | Partner 1 | 2 | 2018 | 12 |
| 2 | Partner 2 | 1 | 2018 | 18 |
| 2 | Partner 2 | 2 | 2018 | 12 |
It should get this with a query:
| Partner_ID | Partnername | up/down |
|------------|-------------|---------|
| 1 | Partner 1 | +2 |
| 2 | Partner 2 | -6 |
I need to get the Subtract value of 2 different months for each Partner.
Every Partner has a tablerow for each month and a value for that month.
Now I need to get If they went up or went down in value since the month before.
Can someone write me a query?
Since you're unable to improve your terrible schema, I recommend you use a (very ugly/hard to maintain and very slow) correlated subquery:
SELECT Partner_ID, Partnername, Year, Month, Total - (
SELECT Total
FROM ext_partnertotals AS prev
WHERE prev.Partner_ID = cur.Partner_ID AND CASE cur.Month
WHEN 1 THEN prev.Year = cur.Year - 1 AND prev.Month = 12
ELSE prev.Year = cur.Year AND prev.Month = cur.Month - 1
END
) AS `up/down` FROM ext_partnertotals AS cur
See it on sqlfiddle.

Creating a crosstab query in MySQL

I have a MySQL table that tracks certain totals by both hour of the day and various locations. I am trying to create a query that will total not only each column, but also each row. The query I have so far totals each column, but I can't figure out how to get a total for each row as well.
This is my query:
SELECT * FROM
(SELECT IFNULL(hour,"Total") as hour, SUM(location1), SUM(location2), SUM(location3), SUM(location4), SUM(location), FROM counts WHERE ay = 'AY1617' GROUP BY hour WITH ROLLUP) as crossdata
ORDER BY FIELD (hour,'8:00am','9:00am','10:00am','11:00am','12:00pm','1:00pm','2:00pm','3:00pm','4:00pm','5:00pm','6:00pm','7:00pm','8:00pm','9:00pm','10:00pm','11:00pm')
This is ultimately what I want the output to look like:
hour location1 location2 location3 location4 totals
8am 4 3 2 1 10
9am 1 2 2 1 6
10am 2 3 2 3 10
totals 7 8 6 5 26
How can I achieve this?
For what it's worth, this is not a crosstab query. You aren't pivoting rows to columns.
I tried this query and got the result you want:
SELECT IFNULL(hour, 'Total') AS hour,
SUM(location1) AS location1,
SUM(location2) AS location2,
SUM(location3) AS location3,
SUM(location4) AS location4,
SUM(location1)+SUM(location2)+SUM(location3)+SUM(location4) AS totals
FROM counts
WHERE ay = 'AY1617'
GROUP BY hour WITH ROLLUP;
You should really use the TIME data type instead of strings for the hour. Then it just sorts correctly.
+----------+-----------+-----------+-----------+-----------+--------+
| hourt | location1 | location2 | location3 | location4 | totals |
+----------+-----------+-----------+-----------+-----------+--------+
| 08:00:00 | 4 | 3 | 2 | 1 | 10 |
| 09:00:00 | 1 | 2 | 2 | 1 | 6 |
| 10:00:00 | 2 | 3 | 2 | 3 | 10 |
| Total | 7 | 8 | 6 | 5 | 26 |
+----------+-----------+-----------+-----------+-----------+--------+

get latest(date) row of groups

my problem is, that I stuck with this I guess simple problem.
Now 2 evenings Grrr...
I created a small example to keep it simple:
The source table looks like that: Some obj with some random status.
These statuses can be changed/updated by insert a new row.
Id | obj| status | date
---+----+--------+-----
1 | 1 | green | 2013
2 | 1 | green | 2014
3 | 1 | yellow | 2015
4 | 1 | orange | 2016 <- Last status of 1
5 | 2 | green | 2013
6 | 2 | green | 2014 <- Last status of 2
7 | 3 | green | 2010
8 | 3 | red | 2012 <- Last status of 3
I would need to get an output like that:
obj| status | date
---+--------+-----
1 | orange | 2016
2 | green | 2014
3 | red | 2012
text: The output shows the latest status of ech obj.
I hope somebody can help me..
A simple correlated subquery in the where clause does the trick:
select obj, status, date
from t
where t.date = (select max(t2.date) from t t2 where t2.status = t.status);
select obj, status, date
from t
where t.date = (select max(t2.date) from t t2 where t2.Obj= t.Obj);

Mapping a column value to which dates it has rows of

I have a table of sign-ins for people who are logging time on different projects and I need to compile a report of which days each project was worked on.
My table looks something like this:
id | project | time_in
----------------------------------
1 | 1 | 2014-12-07 05:00:00
2 | 2 | 2014-12-08 06:00:00
3 | 1 | 2014-12-05 14:00:00
4 | 3 | 2014-12-07 08:30:00
5 | 2 | 2014-12-07 12:00:00
6 | 1 | 2014-12-08 05:00:00
7 | 2 | 2014-12-05 06:00:00
8 | 1 | 2014-12-06 14:00:00
9 | 3 | 2014-12-08 08:30:00
10 | 2 | 2014-12-06 12:00:00
time_in is of type TIMESTAMP.
What I need to figure out is, given a date range (e.g. December 5 - 8), which days of the week each project was worked on. I'm totally flexible on the query, i.e. I can generate the query using a loop, and I'm also flexible on how the result set looks, so long as I can parse it to get the information I need. For example, maybe:
project | days
-----------------------------------------------------
1 | 2014-12-07,2014-12-08,2014-12-05,2014-12-06
2 | 2014-12-08,2014-12-07,2014-12-05,2014-12-06
3 | 2014-12-07,2014-12-08
Or better yet:
project | d0 | d1 | d2 | d3
---------------------------
1 | 1 | 1 | 1 | 1
2 | 1 | 1 | 1 | 1
3 | 0 | 0 | 1 | 1
I honestly have no idea where to even begin on a query like this, if it's even possible.
You could use group_concat to achieve your initial results:
select project, group_concat(date(time_in) order by time_in)
from yourtable
group by project
SQL Fiddle Demo
If you want additional columns, you could use max with case:
select project,
max(case when date(time_in) = '2014-12-05' then 1 else 0 end) d0,
max(case when date(time_in) = '2014-12-06' then 1 else 0 end) d1,
max(case when date(time_in) = '2014-12-07' then 1 else 0 end) d2,
max(case when date(time_in) = '2014-12-08' then 1 else 0 end) d3
from yourtable
group by project
More Fiddle