I have a Google Sheets file with the following data:
Column A
Column B
John
Apple
John
Orange
Mary
Apple
Mary
Kiwi
I would like to find all names that have Apple but not Orange, so in this case, John would not be flagged, but Mary would.
The flagging can be by way of highlighting every row that includes Mary via conditional formatting, or by only showing Mary in a pivot table report (as a single entry, or multiple entries equal to the number of lines).
I tried using pivot table and/or VLOOKUP but haven't figured out how to compare values from different rows.
To get a list of names that match your criteria, use filter() and match(), like this:
=filter(
A2:A,
B2:B = "Apple",
isna(
match(
A2:A,
iferror(filter(A2:A, B2:B = "Orange")),
0
)
)
)
Related
I'm trying to dynamically offset data of multiple rows to match the header column in Google Sheets. The first tab contains data of multiple fruits and how many are harvested on a particular day. Each fruit starts harvesting on different dates, and the dates might not be continuous.
The second tab, "Fruit bank", shows how many fruits are harvested in total for each day. Column D is a continuous set of dates. In cell E1, a QUERY formula dynamically pulls the names of the fruits so whenever a new fruit is added, it shows up here as well. In cell E2 and the rest of the row, I use VLOOKUP formulas to pull the data from the first tab. What I need help with is to write a formula on cell E2 that expands to the rest of the row so I don't have to manually type in the lookup range every time a new fruit is added.
Also, I suspect there're better functions to use than the VLOOKUP because the way VLOOKUP pulls data is very slow. I could literally see it loading even with this small dataset.
Yellow cells contain formula.
I appreciate anyone who can take a look at my spreadsheet (linked below) and see what's the best solution for this. The 3rd tab is editable.
https://docs.google.com/spreadsheets/d/14GeJKgxadInNWVVyft2gilae7HOIEvKXRop-Kz_On-Q/edit#gid=53523977
Thanks! J
Use filter(), like this:
=arrayformula(
ifna(
vlookup(
$D2:$D,
{
filter(
'Fruits data'!$B2:$AA,
'Fruits data'!$A1:$Z1 = E1
),
filter(
'Fruits data'!$A2:$Z,
'Fruits data'!$A1:$Z1 = E1
)
},
2, false
)
)
)
See your sample spreadsheet.
you can try either. added solutions here and here
=BYROW(D2:D,LAMBDA(dx,IF(dx="",,BYCOL(E1:1,LAMBDA(ex,IF(ex="",,XLOOKUP(dx,FILTER('Fruits data'!1:46,COLUMN('Fruits data'!1:1)=MATCH(ex,'Fruits data'!1:1,0)-1),FILTER('Fruits data'!1:46,'Fruits data'!1:1=ex),)))))))
OR
=MAKEARRAY(COUNTA(D2:D),COUNTA(E1:1),LAMBDA(r,c,XLOOKUP(INDEX(D2:D,r),FILTER('Fruits data'!1:46,COLUMN('Fruits data'!1:1)=MATCH(INDEX(E1:1,,c),'Fruits data'!1:1,0)-1),FILTER('Fruits data'!1:46,'Fruits data'!1:1=INDEX(E1:1,,c)),)))
try this with dates:
=ARRAYFORMULA(QUERY({
FLATTEN(FILTER('Fruits data'!A2:100, ISODD(COLUMN('Fruits data'!A2:2)))),
FLATTEN(FILTER('Fruits data'!A2:100, ISEVEN(COLUMN('Fruits data'!A2:2)))),
FLATTEN(IF(FILTER('Fruits data'!A2:100, ISEVEN(COLUMN('Fruits data'!A2:2)))="",,
FILTER('Fruits data'!A1:1, ISEVEN(COLUMN('Fruits data'!A2:2)))))},
"select Col1,sum(Col2) where Col2 is not null group by Col1 pivot Col3"))
which could be simplified:
=ARRAYFORMULA(LAMBDA(x, QUERY({
FLATTEN(FILTER(x, ISODD(COLUMN(X)))),
FLATTEN(FILTER(x, ISEVEN(COLUMN(x)))),
FLATTEN(IF(FILTER(x, ISEVEN(COLUMN(x)))="",,
FILTER(OFFSET(x, -1,,1), ISEVEN(COLUMN(x)))))},
"select Col1,sum(Col2) where Col2 is not null group by Col1
pivot Col3 label Col1'Date'"))('Fruits data'!A2:100))
I am struggling to find a way to use a VLOOKUP where the both the search_key and range are 2 columns. In both sheets (seperate workbooks for which I am using IMPORTRANGE) I have 2 columns with First Name and Last Name. The Sheet1 also contains the Hire Date, and I would like to populate the Hire Date from Sheet1 into a column in Sheet2.
I accomplish what I want if I merge the First Name and Last Name into a single column on both sheets. Unfortunately, this cannot be a permanant solution since there are other dependancies where the names must remain seperate columns.
I have created a test worrkbook to showcase the issue.
https://docs.google.com/spreadsheets/d/1v3coBJRwJEbrrdgcflV4-dssKgknS-T2werWVjPwxEA
Put this formula in cell Sheet2!C1:
=arrayformula(
iferror(
vlookup(
A1:A & B1:B,
{ Sheet1!A1:A & Sheet1!B1:B, Sheet1!C1:C },
2, false
)
)
)
Then format the result column as Format > Number > Date.
I have two column in a Google sheet that have values in them. Column A has all possible values (inclusive duplicate values) and Column B has some of the values in A (also inclusive duplicates).
I wanted to find out which values in Column A do not appear in Column B, also taking into account number of occurrences of these values.
The MATCH function works well however I wanted to have three instances of HQR123 appearing in the Pending column, as there are 4 occurrences of this value in Column A vs only 1 occurrence in Column B. If another instance of HQR123 is entered in Column B then only two instances should appear in the Pending column.
Is this possible?
Thanks and regards,
Shalin.
You could try something like
=sort(
index(
filter(A2:A,
isna(
match(A2:A&countifs(A2:A, A2:A, row(A2:A), "<="&row(A2:A)),
B2:B&countifs(B2:B, B2:B, row(B2:B), "<="&row(B2:B))
, 0)
))))
Suppose we have the following table in Google Sheets:
A
B
C
D
E
1
a
green apple
apple
=SUMIFS(A:A, B:B,"*" & D1 & "*", C:C,"*"&D1&"*")
1
Orange
banana
=SUMIFS(A:A, B:B,"*" & D2 & "*", C:C, "*" & D2 & "*")
20
a
red apple
1
banana
1
kiwi
1
Banana
Then E1 == 0 and E2 == 2. This is because SUMIFS sums the values of B column if ALL the criteria for all ranges are TRUE, this is equivalent to say that SUMIFS joins all criteria with an AND (logical) operator.
What I need is the same SUMIFS operation but with an OR operator so that E1 == 21.
One solution is to concatenate B and C values in F column and then simply use this formula
=SUMIF(F:F, "\*" & D1 & "\*", B:B)
Is there another way to do this without having to create another column?
Since someone edited the tags, the answer can be written for Google Sheets, Excel, LibreOffice and similar apps. Thanks for you help!
If your real application only needs to find any items from D:D in either of only two columns and then return one final total, you can use this:
=ArrayFormula(SUM(FILTER(A:A,NOT(ISERROR(REGEXEXTRACT(LOWER(B:B&"~"&C:C),JOIN("|",FILTER(LOWER(D:D),D:D<>""))))))))
If your real application needs to find any items from D:D in more that two columns and then return one final total, you can either continue to join columns like this — B:B&"~"&C:C — or use a formula like this:
=ArrayFormula(SUM(FILTER(A:A,NOT(ISERROR(REGEXEXTRACT(LOWER(TRANSPOSE(QUERY(TRANSPOSE(B:C),,COLUMNS(B:C)))),JOIN("|",FILTER(LOWER(D:D),D:D<>""))))))))
If you need a per-item count of the strings in D:D if they appear any number of times in other columns, try this:
=ArrayFormula(QUERY(TRIM(QUERY(SPLIT(FLATTEN(IF(NOT(ISNUMBER(SEARCH(TRANSPOSE(FILTER(D:D,D:D<>"")),LOWER(TRANSPOSE(QUERY(TRANSPOSE(B:C),,COLUMNS(B:C))))))),,TRANSPOSE(FILTER(LOWER(D:D),D:D<>""))&"~"&A:A)),"~"),"Select Col1, SUM(Col2) WHERE Col1 Is Not Null GROUP BY Col1 LABEL SUM(Col2) ''")),"WHERE Col2 Is Not Null"))
If there will only ever be 2 columns to consider, then it makes sense to go with JohnSUN's suggestion from the comments.
Otherwise:
=SUMPRODUCT(N(MMULT(N(ISNUMBER(SEARCH(D1,B$1:C$6))),TRANSPOSE(COLUMN(B$1:C$6)^0))>0),A$1:A$6)
The range referenced (B$1:C$6) can be extended to one comprising as many columns as desired, though bear in mind that, having switched from a SUMIF set-up to a SUMPRODUCT one, you would be strongly advised to not use entire column references (at least in Excel this is the case; not sure about Sheets).
I have a Google Sheet (Test Sheet 2) with two sheets in it, Sheet 1 and Sheet 2. Sheet 2 is where all of the data is and I need to get the sums of the counts of that column based on three criteria into sheet 1 column C. The name, week, year and count need to match up. I used the formula
=arrayformula(iferror(vlookup(A2:A&2020&B2:B, {Sheet2!A2:A&Sheet2!B2:B&Sheet2!C2:C, Sheet2!D2:D}, 2, FALSE)))
but that only works for unique rows. In the example sheet I am providing, the formula works well for Bill, Lisa, Katie and Jon because they all have one value for 'count' from Sheet2 when the parameters of name, week and year match up. But Mike has two rows matching the criteria. This formula returns the first match which is 3. The other value is 4 so I would like the count in Sheet1 to show 7 instead of 3. I need it to add them up.
I also tried to use sumifs but the columns are two different sizes so that didn't work.
Any idea? I did try to combine sumif with the above formula but that did not work either.
Link to Test Sheet
Solution with ARRAYFORMULA and SUMIF
If you need to use ARRAYFORMULA to improve the performances you can use this tweak of the SUMIF statement: basically you can concatenate the conditions to make them create a single AND condition.
This would be a possible solution for the formula in your comment:
=ARRAYFORMULA(SUMIF(Sheet2!A2:A&Sheet2!B2:B,A2:A&2020,Sheet2!D2:D))
Solution with SUMIFS
If you are looking for a solution with the SUMIFS formula you can use this:
SUMIFS('sum_range', 'criteria_range', condition, ['criteria_range_2', condition_2])
In your case this will translate to:
=SUMIFS(Sheet2!D2:D, Sheet2!A2:A, A2, Sheet2!B2:B, 2020)
In this case the ranges dimensions won't affect the formula execution.
Just drag this formula for the Sheet1 table column and you will get the results. The drawback is that you cannot use ARRAYFORMULA with SUMIFS. Performance wise, if you have a lot of rows in the Sheet1 I suggest using the ARRAYFORMULA solution, since this will trigger a lot of formula calls instead of just one.
Try this query()
=query(Sheet2!A:D, "Select A, C, sum(D) where B = 2020 group by A, C label C 'Week', sum(D) 'Count'", 1)
UPDATED:
If you really need to use vlookup in arrayformula() you can always ise the query (that deals with the summing) as the lookup range. In the spreadsheet I used
=ArrayFormula(if(len(A2:A), iferror(vlookup(A2:A&year(D2:D)&E2:E, query({Sheet2!A:A&Sheet2!B:B&Sheet2!C:C, Sheet2!D:D}, "Select Col1, sum(Col2) where Col1 <>'' group by Col1", 1), 2, 0)),) )
and see if that helps?