Was curious why Formula 2 (below) doesn't work, i.e. returns just a zero and not an array whereas Formula 1 works (below). The argument construction seems is similar.
DM:DM is list of employers. (not unique employers, i.e. Bob post several jobs)
DW:DW is # of positions offered for a particular job.
DU:DU is type of job.
DM DW DU
Bob 3 Sales
Alice 10 Cashier
Mike 4 Clerk
Bob 1 Sales
I think the issue is the way I am using the "Unique" function nested inside countifs vs. sumifs and wrapping this inside an arrayformula. In Formula 1, the array returns number of job posts for unique employer, and so Bob 2, Alice 1, Mike 1. What I was attempting in Formula 2 was Bob 4, Alice 10, Mike 4. I could accomplish this by separating multiple columns and functions but I wondered if anyone knew of an elegant way to do this using arrayformula so I have it in one column. Thanks and I hope this question was clear.
Formula 1
=arrayformula(countifs('Data (QC)'!DM:DM,UNIQUE('Data (QC)'!DM:DM),'Data (QC)'!DU:DU,"Shop Sales Assistant"))
Formula 2
=arrayformula(sumifs('Data (QC)'!DW:DW,'Data (QC)'!DM:DM,unique('Data (QC)'!DM:DM),'Data (QC)'!DU:DU,"Shop Sales Assistant"))
=arrayformula ( unique ({filter( Log!M2:M, Log!M2:M<>"" ), sumif ( filter ( Log!M2:M, Log!M2:M<>"" ), "=" & filter ( Log!M2:M, Log!M2:M<>"" ), Log!W2:W )}))
try:
=QUERY(A2:C, "select A,sum(B) where A !='' group by A label sum(B)''", 0)
and for count:
=QUERY(A2:C, "select A,count(B) where A !='' group by A label count(B)''", 0)
Related
Feels like this may be a basic, but I cannot find a way to do this with sumifs.
I've got four columns in one table, representing the workload of an employee like this:
Job
Employee # 1
Employee # 2
Workload
Job 1
Bob
Jane
5
Job 2
Bob
2
Job 3
Jane
Susan
3
Job 4
Susan
2
I'd like to output total workflow results to a second sheet for each employee based on a specialized formula. In English, the forumla would be:
Calculate the total workload for each employee.
- For each job that includes that includes employee named "X" and no assigned teammate, use the job's corresponding workload value.
- For each job that includes that includes employee named "X" and has an assigned teammate, reduce the corresponding workload value by 50%.
So with the given table above, I'd want an output like this:
Employee Name
Workload
Bob
4.5
Jane
4
Susan
3.5
Math:
Bob = ((job_1 / 2) + job_2)
Jane = ((job_1 / 2) + (job_3 / 2))
Susan = ((job_3 / 2) + job_4)
Does anyone know how I can accomplish this?
Functions like sumifs seem to only let me set criteria to sum or not sum a value. But I cannot find a clear way to sum only 50% of a value based on a condition in a separate column.
=LAMBDA(name,SUMIFS(D2:D5,B2:B5,name,C2:C5,"")+SUMIFS(D2:D5,B2:B5,name,C2:C5,"<>")/2+SUMIFS(D2:D5,C2:C5,name)/2)("Bob")
The math is
SUM D, if B is Bob and C is empty and
SUM half of D if B is Bob and C is not empty and
SUM half of D, if C is Bob.
Or the same logic via query:
=QUERY(
{
QUERY(B1:D5,"Select B,sum(D) where C is null group by B");
QUERY(B1:D5,"Select C,sum(D)/2 where C is not null group by C");
QUERY(B1:D5,"Select B,sum(D)/2 where C is not null group by B")
},
"Select Col1, sum(Col2) where not Col1 contains 'Employee' group by Col1"
)
However, note that we're assuming title contains Employee and no other names contain Employee.
Employee # 1
sum sum Workload
Bob
4.5
Jane
4(Incorrect in the question)
Susan
3.5
Use this formula
=ArrayFormula({ "Employee Name", "Workload";
QUERY(
QUERY({LAMBDA(a,b,c,d,k, {b,a,{d/k};c,a,{d/k}} )
(A2:A,B2:B,C2:C,D2:D,
BYROW(B2:C, LAMBDA(c, IF(COUNTA(c)=0,,IF(COUNTA(c)=1,1,2)))))},
"Select (Col1),sum(Col3) Group by Col1" ,0), "Where Col1 <> '' ",0)})
Used formulas help
ARRAYFORMULA - QUERY - LAMBDA - BYROW - IF - COUNTA - SUM
I have a sheet and I want to recalculate the formulas until the criteria is met.
I am supplying this demo sheet to show what I want to achieve.
I have a list in Col A. Im picking 10 random from the list in B. Checking Unique in C. Counting number of Unique values in D.
I have a condition set in E1 which test the D1 value. Above 5 is good. Under 5 is bad and requires a refresh to recalculate the formulas to obtain a new random list till it goes above 5.
Any suggestion how can I achieve this please?
I thank you in advance for your guidance.
LINK TO MY SHEET
NOTE: I am not looking for solutions to generate X number of random values from the list. I want to know if it is possible to implement like a 'while loop' in google sheets. Recalculate formulas until the condition is fulfilled then stop.
use:
=QUERY(UNIQUE(SORT(A2:A, RANDARRAY(ROWS(A2:A)), 1)),
"where Col1 is not null limit 10", )
if you want "above 5" use:
=QUERY(UNIQUE(SORT(A2:A, RANDARRAY(ROWS(A2:A)), 1)),
"where Col1 is not null limit 6", )
I believe what I am trying to do should be simple in Google Sheets formulae, but any solution based on an Excel formula should be easily transferable.
Because additional characters will be added periodically, I have a named range: "Heroes".
Heroes
Bilbo
Gandalf
Saruman
Wormtongue
Tom Bombadil
For each hero, I have a worksheet in one overall workbook. On these worksheets, there are columns for Date, Time, Quest, and Count. Several times per day, a hero will venture out on a quest of a certain type, returning with a certain count as a prize. Each venture has its own row distinguishable by date and time. Eg-:
Date
Time
Quest
Count
12/4
3:00P
Ring
9
12/5
8:00A
Mordor
6
12/5
4:15P
Sting
3
Meanwhile, I have a summary worksheet, on which I am manually entering (for now... bonus points to help create an =arrayformula() or equivalent to grab all unique date/time combinations from each character's worksheet) the date and time at which one or a batch of heroes are sent to quest. I am trying to figure out the formula template that will sum the counts for each quest type for each hero at the specific date and time signified by its corresponding row (starting at 12/4, 3:00P, Ring, the count should be 9, for example, which is Bilbo's prize for questing at that time; of course, other heroes are also sent out at 3:00P, resulting in prizes for the other quests, and multiple heroes may venture on the same type of quest at any given time):
Date
Time
Ring
Sting
Mordor
Moria
12/4
3:00P
9
3
4
1
12/4
9:30P
1
0
8
0
12/5
8:00A
5
3
6
9
12/5
12:10A
3
1
3
8
12/5
4:15P
4
5
2
5
Since not every date and time in the summary sheet will exist on each hero's worksheet, I seem unable to use "SUMIFS", which functions in such a way that each sum_range and criteria_range are added on only across the same row when conditions are met. I think there is a SUMPRODUCT(), or INDEX(MATCH()) way to do this, but when including the named range to read across multiple worksheets, only the first hero's numbers were added in my tinkering with this.
I'm dancing around the solution here. Anyone care to tango ? Many thanks !
Sample Workbook for support: https://docs.google.com/spreadsheets/d/142IE9r2ip6YHsGdMr-zt_IHd6W7glqUId_UiGQnCUZs/edit?usp=sharing
it would be done like this:
=QUERY({Bilbo!A:D; Gandalf!A:D; Saruman!A:D; Wormtongue!A:D; 'Tom Bombadil'!A:D},
"select Col1,Col2,sum(Col4) where Col1 is not null group by Col1,Col2 pivot Col3", 1)
if you want a specific order of places you can do:
=TRANSPOSE(SORT(TRANSPOSE(QUERY(
{Bilbo!A:D; Gandalf!A:D; Saruman!A:D; Wormtongue!A:D; 'Tom Bombadil'!A:D},
"select Col1,Col2,sum(Col4) where Col1 is not null
group by Col1,Col2 pivot Col3", 1)),
MATCH(FLATTEN(QUERY(QUERY(
{Bilbo!A:D; Gandalf!A:D; Saruman!A:D; Wormtongue!A:D; 'Tom Bombadil'!A:D},
"select Col1,Col2,sum(Col4) where Col1 is not null
group by Col1,Col2 pivot Col3", 1), "limit 0", 1)),
{"Date"; "Time"; "Ring"; "Sting"; "Mordor"; "Moria"}, ), 1))
or manually like this:
=QUERY(QUERY({Bilbo!A:D; Gandalf!A:D; Saruman!A:D; Wormtongue!A:D; 'Tom Bombadil'!A:D},
"select Col1,Col2,sum(Col4) where Col1 is not null group by Col1,Col2 pivot Col3", 1),
"select Col1,Col2,Col5,Col6,Col3,Col4")
if you thinking to outsmart it with the list of Heroes... don't. referring a range from other sheets requires the usage of INDIRECT. and surprise surprise, INDIRECT is not supported under ARRAYFORMULA so you cant build an array. at this point, you either re-think your life choices or you use a script where there is support for such indirected arrays. the best you can do without script is to hardcode it like:
=QUERY({
INDIRECT(Main!A2&"!A:D");
INDIRECT(Main!A3&"!A:D");
INDIRECT(Main!A4&"!A:D");
INDIRECT(Main!A5&"!A:D");
INDIRECT(Main!A7&"!A:D")},
"select Col1,Col2,sum(Col4) where Col1 is not null
group by Col1,Col2 pivot Col3", 1)
and ofc this will only work if sheet exists on the list and list does not contain empty cells otherwise you will get ARRAY error like this because Main!A6 sheet does not exist:
so to counter it we can do some slide of hand tricks with IFERROR which will allow us to not get the error and still use non-existent sheets and even empty cells so we can pre-program it for future additions like this:
=QUERY({
IFERROR(INDIRECT(IF(Main!A2="", 0, Main!A2)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A3="", 0, Main!A3)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A4="", 0, Main!A4)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A5="", 0, Main!A5)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A6="", 0, Main!A6)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A7="", 0, Main!A7)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A8="", 0, Main!A8)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A9="", 0, Main!A9)&"!A:D"), {"","","",""});
IFERROR(INDIRECT(IF(Main!A10="", 0, Main!A10)&"!A:D"),{"","","",""});
IFERROR(INDIRECT(IF(Main!A11="", 0, Main!A11)&"!A:D"),{"","","",""})},
"select Col1,Col2,sum(Col4) where Col1 is not null
group by Col1,Col2 pivot Col3", 1)
note: 4 columns in range A:D = 4 empty cells {"","","",""}
I have simple table that looks like this:
All i need is to SUM points for specific player (John) in his last 3 matches.
I was able to come with this formula:
SUMPRODUCT(LARGE((A2:B="John")*(C2:D);{1;2;3}))
The problem is that instead of what I was looking for, it sums the highest 3 values, that can be anywhere in that range.
Is there some similar formula, that can do only the last 3 matches?
I think a SUMPRODUCT can get you there with some constructed arrays using a COUNTIFS() and ROW() to get the most recent 3.
This formula:
=SUMPRODUCT((COUNTIFS(A:B,G2,ROW(A:B)*{1,1},">="&ROW(A:B)*{1,1})<=3)*(A:B=G2),C:D)
on this sheet I made seems to work.
I thnk I have a formula that gives what you want. It's not pretty, and I'm sure it can be made simpler, but this works:
=query( query(
{ arrayformula( {ROW(A1:A) } ),
query(A1:D,"select A, B, C, D",1)
} , "select * order by Col1 desc",1),
"select Col2, Col3, Col4, Col5
where (Col2 ='John' or Col3 = 'John')
order by Col1 desc limit 3",1)
Basically, it adds the row number as an extra column to the data, so that we can sort the data in reverse order by row number. Then we query the result to find the first three occurences of 'John', in either Col A or Col B.
Here is a sample sheet:
https://docs.google.com/spreadsheets/d/1-mhTb5Cpp3D-1OltlmCfwlmM-vc2OknHxfJAyHD7BjI/edit?usp=sharing
Credit to Erik Tyler for a previous answer on a different question, on how to add the row number to a query.
Edit: Updated the sheet to provide the SUM of John's (or any player's) scores from the last three matches. This can be combined with the previous formula, if you want a single formula to place somewhere. Or will you have a list of all the players, and you'll want their last three scores beside each of their names?
If I can simplify the formula, I'll update it here.
Let me know if you need something more than this, or if this has answered your question.
Approach
I would use the query formula to get the cells that you need so that you can leverage the limit statement.
You should put a column with the indexes so that you can order the cells in descending order and take the first 3.
Given that your table headers are:
+-----------------------------------------------+
| INDEX | NAME 1 | NAME 2 | POINTS 1 | POINTS 2 |
+-----------------------------------------------+
I would use this query to get your desired result:
=SUMPRODUCT(QUERY(A2:E, "Select D * E where B = 'John' or C = 'John'" order by A desc limit 3"))
Let's say I have the following spreadsheet:
https://docs.google.com/spreadsheets/d/1FY7GnhZoT2_Tzm8FLOkDuc5XR8TkFhBJKgW_qZ1r4Cc/edit?usp=sharing
On the top left column, I have a formula that counts the events and sorts them according to the frequency. Anyway, what I want to do now is instead of just counting the frequencies of the actions, I want to count the number of unique actions. For example, in my spreadsheet, the action call came up 5 times: 2 times by Joe, 2 times by Mary, 1 times without a user (empty). Therefore, next to the call action on my left-hand table, I would want 2 because the number of unique pairs (event and user) is exactly 2.
So using the above logic, what I want my left side table to be is the following:
Call 2
SMS 1
Review 1
Hopefully, I have made myself clear.
How can I do this using my example spreadsheet? Thanks.
try:
=ARRAYFORMULA(QUERY(UNIQUE({D:D, D:D&E:E, E:E}),
"select Col1,count(Col1)
where Col3 != ''
group by Col1
order by count(Col1) desc
label count(Col1)'Count'", 1))