I have a list that contains multiple items. However, each item has different variants.
I want to sum all occurrences of each item, regardless of the variant.
I am using the COUNTIFS function in Google Sheets but for the criteria, I want to input a range that is an array of strings.
=countifs(!A:A,("B:B"),!C:C,"small")
Where column B includes a list of different variant names and column C is sizing.
For example:
A
B
C
apples
apples
small
apples
applez
small
applez
applees
small
appleees
small
oranges
small
In this case I would want the result to = 4 because there were four total instances in column A where the criteria was met (using any string/row in column B) and since all sizes were small.
I was able to get the result I wanted using this formula however it is extremely cumbersome as there are many variants and they are constantly updated/changed concurrently in column B:
=countifs(A:A,"item variant 1",C:C,"small")
+countifs(A:A,"item variant 2",C:C,"small")
+countifs(A:A,"item variant 3",C:C,"small")
+countifs(A:A,"item variant 4",C:C,"small")
+countifs(A:A,"item variant 5",C:C,"small")
Seeking any improvement at all from there, I tried listing the variants within a range itself (making sure to use a semicolon for Google Sheets based on this answer) and couldn't get that to work either:
=countifs(A:A,{"item variant 1";"item variant 2";"item variant 3";"item variant 4";"item variant 5"},C:C,"small")
In the above case, it only counts instances of first variant mentioned in the range (in this case item variant 1).
while you said the expected output is 4,
I can only see 2 unique items matching for a count of 3(apples, applez)
& orange has zero match
& appleees not a match to applees
formula:
=COUNTA(IFERROR(filter(A:A,(C:C="small")*(REGEXMATCH(A:A,TEXTJOIN("|",1,B2:B))))))
Alternate formula:
=COUNTA(ARRAYFORMULA(IF(LEN(A2:A)*(C2:C="small"),IFERROR(vlookup(A2:A6,B:B,1,)),)))
Try this formula:
Assume that your data are always arranged as {ITEMS,VARIANTS,SIZES},
In this formula, you can adjust data range and search criteria according to the values in the last () (current values are $A:$C and "small"),
this formula...
uses BYROW() to iterate VARIANTS column and...
use QUERY() to filter ITEMS column for matches according to VARIANT and... FINDSIZE as criteria,
COUNT() the output of the filters by QUERY(), SUM() the RESULTS of all filters to get 3, since only apples and applez of the given VARIANTS has matches. (applees in VARIANTS has only 2 'e's while appleees in ITEMS has 3 'e's, makes it a non-match)
=ArrayFormula(
LAMBDA(RANGE,FINDSIZE,
LAMBDA(DATA,FINDSIZE,
LAMBDA(ITEMS,VARIANTS,SIZES,
LAMBDA(RESULTS,
SUM(RESULTS)
)(
BYROW(VARIANTS,LAMBDA(VARIANT,
LAMBDA(FILTER,
SUM(IFNA(FILTER,0))
)(QUERY({ITEMS,SIZES},"SELECT COUNT(Col1) WHERE Col1='"&VARIANT&"' AND Col2='"&FINDSIZE&"' LABEL COUNT(Col1)''",0))
))
)
)(INDEX(DATA,,1),QUERY({RANGE},"SELECT Col2 WHERE Col2 IS NOT NULL",0),LOWER(INDEX(DATA,,2)))
)(QUERY({RANGE},"SELECT Col1,Col3 WHERE Col1 IS NOT NULL OR Col3 IS NOT NULL",0),LOWER(FINDSIZE))
)($A:$C,"small")
)
If you don't concern the accessibility of the range and criteria, here is a shorter version:
=SUM(BYROW(B:B,LAMBDA(VARIANT,IFNA(IF(VARIANT="",0,QUERY({A:A,C:C},"SELECT COUNT(Col1) WHERE Col1='"&VARIANT&"' AND Col2='small' LABEL COUNT(Col1)''",0)),0))))
Related
A spreadsheet contains multiple rows and columns with names (in varying order), the same name can appear in multiple places, but not necessarily in the same column or row.
Looking to list all names and count the number of times each name appears (no duplicates).
Tried the UNIQUE in combination with COUNTIF, but I can't seem to make them work together. :(
I'm sure there's some way of nesting formulas to tabulate the results, but I just can't wrap my head around it.
You can select your whole range in a query like this (change A2:F with your desired range)
=QUERY(FLATTEN(A2:F),"SELECT Col1,COUNT(Col1) where Col1 is not null group by Col1")
See this answer on how to stack unique counts when values are in multiple columns.
For example if your data is in A1:D10:
=UNIQUE({A1:A10;B1:B10;C1:C10;D1:D10})
Will return a (vertical) list of all unique values. Then use countif in a new column on the whole range (rows, columns) with condition on each of the unique values.
Any help in figuring this out would be appreciated. I would like a forumla to calculate the number of times a code number appears more than once AND where type is A.
A sample set of data looks like the following:
In this case the forumla should return 1 as there is one case of a repeated code number (1) where type is (A) - first row and last row in this case.
Would the forumla be any different if I also had a third column and wanted that to be a certain value as well? Again with the test data below I would want this to return 1 in the case that I wanted to measure the number of times any code number appeared more than once where type=A and subtype=C:
.
Ihave started with the following which identifies the number of unique combinations in columns A and B, but I can't seem to add any way to only return where a particular combination appears more than once:
=COUNTUNIQUE(IFERROR(FILTER(A2:A,B2:B="A"),""))
I have tried the following but it doesn't return correctly:
=COUNTUNIQUE(IFERROR(FILTER(A2:A,B2:B="A",COUNTIF(A2:A,A2:A)>1)))
Been trying to figure this one out for a while with no success.
Thank you
You can try this (TABLE = the range corresponding to your dataset, including the header row):
=query(query(transpose(query(transpose(TABLE),,9^9)),"select Col1,count(Col1) where Col1 contains 'A' group by Col1",1),"select Col2-1 where Col2>1 label Col2-1 ''")
What we are doing is to concatenate the Code number & type columns into one using the TRANSPOSE/QUERY/TRANSPOSE...9^9 hack, querying it again to make a temporary table of each group against its count for those groups which meet the criteria, then finally subtracting one from each group count and only returning an answer if there were groups with count>1 to begin with. You will get multiple results if multiple groups satisfy the count>1 criteria.
To add the subtype column to the formula as per the second question, change TABLE to suit, then change the inner QUERY to:
"select Col1,count(Col1) where Col1 contains 'A' and Col1 contains 'c' group by Col1"
Note that the if your 'real' type & subtype categories share characters then the where/contains approach in the QUERY will fail and a different approach will be needed.
Assume that you place you data at A1:B10, what this function do is:
FILTER B1:B10 by type, which is "A" in this example, and return an array which is filtered A1:B10.
Use INDEX to extract only the 1st column, which is the code column of the filtered array, and name it 'DATA' with LAMBDA function.
Use BYROW to iterate 'DATA', and check each code with COUNTIF, if it counts more than one of this code in the filter result, return that code, else return "".
Use UNIQUE to get rid of duplicate results. (since we are looking for code which have more than 1 repeats, so the return array will sure have duplicates.)
Use query to get rid of the extry empty rows.
=QUERY(UNIQUE(
LAMBDA(DATA,
BYROW(DATA,LAMBDA(ROW,
IF(COUNTIF(DATA,ROW)>1,ROW,"")
))
)(INDEX(FILTER(A1:B10,B1:B10="A"),,1))
),"WHERE Col1 IS NOT NULL")
Just noticed that the INDEX function is not necessary, FLITER can directly returns A1:A10 according the compare results of B1:B10.
=QUERY(UNIQUE(
LAMBDA(DATA,
BYROW(DATA,LAMBDA(ROW,
IF(COUNTIF(DATA,ROW)>1,ROW,"")
))
)(FILTER(A1:A10,B1:B10="A"))
),"WHERE Col1 IS NOT NULL")
I would like to calculate the sum and average in Google Spreadsheet of a range based on conditions from another column, but treat blanks with a specified value. It can be accomplished using a helper column, but I would like to do it without it. Here is the sample data:
I would like to sum values in column B based on value on Column A, but replacing blanks values with the value specified on E2 and E3 respectivelly.
Here is a sample in google sheet:
https://docs.google.com/spreadsheets/d/1Cv9YxFMHuGq2biNNCdGsjU8cAD_OwCPTR4YCPLc2r34/edit?usp=sharing
I was trying to use the following formulas for the sum of team A but I am not getting the expected result:
=sumif(A2:A,"A", if(B2:B<>"",B2:B,E2)) returns 6 instead of 19
=sum(if(A2:A="A",if(B2:B<>"", B2:B, E2),)) return 27 instead of 19
I cannot use a combintation of sumif and arrayformula like this because it expects a range in the third input argument:
=sumif(A2:A,"A", ARRAYFORMULA(if(B2:B<>"", B2:B,E2)))
I wasn't going to jump in on this one, since it's after midnight and I didn't feel I had the energy to both write and explain such a formula. But I see that you yourself have helped others on this forum. So I'll soldier through for you.
Delete everything from columns G:I (i.e., leave those columns entirely blank); and I suggest removing all of the formatting that you currently have in place in those columns, since it won't make sense after what I propose below.
Place the following formula in G1:
=ArrayFormula(QUERY(FILTER({A2:A,IF(B2:B="",IFERROR(VLOOKUP(A2:A&"*",D:E,2,FALSE),0),B2:B)},A2:A<>""),"Select Col1, SUM(Col2), AVG(Col2) GROUP BY Col1 LABEL Col1 'Team', SUM(Col2) 'Sum', AVG(Col2) 'Average'"))
This one formula will generate all headers, team names and results for all teams' sums and averages.
The virtual array between the curly brackets pairs every element of A2:A with the results of the IF function. That IF function checks to see if B2:B is blank. If so, a VLOOKUP with wildcard is performed to find the Col-A team name at the start of any value in Col D and, if found, returns the corresponding filler value from Col E. (If not found, IFERROR returns 0 as the filler value. It's important to have a numerical value because of the way QUERY works.)
FILTER filters in all of the above results only for those rows where A2:A contains a non-null value.
QUERY then pulls the team names, sums and averages; the LABEL portion of the QUERY assigns your desired column headers to the results.
This formula is not restricted to only two teams. You can add as many teams as you like in A:B and assign as many filler values as necessary in D:E.
It's important to note, however, that the formula relies on the FULL team name found in A:A being found at the beginning of the Col-D values. So if your team name is "Bears," just make sure the corresponding entry in Col-D starts with "Bears" as well (e.g., "Bears blanks" or even just "Bears").
You'll need to format the entire Col H as whole numbers and the entire Col I as 0.00 to match the results you shown in your sample.
ADDENDUM (after further comments from OP):
It seems that what you're saying is that the D:E values in your sample spreadsheet were something you wanted included within the formula itself and that you did not intend for them to be used as a reference list. I think your post's reference to "without a helper column" may have been your attempt to say this; but it was not clear, as with or without that D:E list as a live reference range, the main formula may have relied on its own helper column in addition to that list.
If you want a formula that contains the list:
=ArrayFormula(QUERY(FILTER({A2:A,IF(B2:B="",IFERROR(VLOOKUP(A2:A,{"A",2;"B",4},2,FALSE),0),B2:B)},A2:A<>""),"Select Col1, SUM(Col2), AVG(Col2) GROUP BY Col1 LABEL Col1 'Team', SUM(Col2) 'Sum', AVG(Col2) 'Average'"))
To add further blank-values, just keep adding to this section...
{"A",2;"B",4}
... being sure to follow the pattern of team-comma-value-semi for all but the last entry which will not need the closing semi.
You can use a combination of sumifs and countifs
to add up the non-blanks
=sumifs(B2:B10,A2:A10,"A")
to add up the blanks (and multiply by the default value)
=countifs(A2:A10,"A",B2:B10,"")*E2
all together
=sumifs(B2:B10,A2:A10,"A")+countifs(A2:A10,"A",B2:B10,"")*E2
Average (use countifs to work out how many items):
=(sumifs(B2:B10,A2:A10,"A")+countifs(A2:A10,"A",B2:B10,"")*E2)/countifs(A2:A10,"A")
I have the following spreadsheet containing information about some courses.
I would like to sum the ECTS column but also group the sums by their type General or Tech. E.g here I would have end up with two cells. One containing the number 5 (Total sum of ECTS for courses with type Tech) and another cell containing the number 27.5 (Total sum of ECTS for courses with type General).
Can this be achieved somehow?
Boris, here is a general formula:
=query(A1:E,"select E,sum(C) where E<>'' group by E",1)
This would return a mini-table of the results.
To get just the two cells, modify the above formula to this
=query(A2:E,"select sum(C) where E<>'' group by E
order by sum(C) label sum(C) '' ",0)
You might need to sort them ("order by") a different column to get them in the order your want - this sorts them by increasing value.
UPDATE:
Further explanation of the formula:
" where E<>'' " is effectively saying where (column) E is not equal to blank. It is important to note that query only works reliably with consistent data - only numbers or only text/strings in each column. It will still run if you have mixed data, but the results can be surprising, and query tends to look at what the majority of the data in a column is, either text or numberic.
So the above test will only work for a text column. If you are looking for numbers, you would not use the single quotes, just the equal sign. Eg. where E <> 0 would find rows with numbers not equal to zero in column E.
order by does sorting of the resuslts by one or more columns, and can specify ascending or descending order.
And label sum(C) '' turns off the column header that the query adds when you include an aggregating function like "sum". Or it can be used to re-label the default heading to something else - label sum(C) 'Calculated Sum'
References:
Query - general usage
Query - detailed reference
Formula:
=query(B19:C23, "select sum(B) group by C", -1 )
Everything in the image should be self descriptive.
=SUMPRODUCT(--(B1:B8="a"), A1:A8)
another way to do it using SUMPRODUCT function
B1:B8 : checks for text "a"
-- : the operator decodes True as 1 and False as 0.
A1:A8 : Values to be taken and added
Using only native Google Sheets functions (no scripts), how can I return a slice of values between two given indices from =INDEX() or another range reference?
Example
If:
=INDEX("Apple", "Banana", "Curant", "Delicious", "Eggplant", "Fruit")
and given indices are 3 and =LEN(INDEX(...))
then desired returned output is:
{"Curant", "Delicious", "Eggplant", "Fruit"}
Note
Use of =INDEX() is preferable but other native solutions are great too.
Use-case requires that the solution be able to take dynamic input as part of a larger function, rather than being given explicit ranges as input.
Solution can be inclusive or exclusive of the given indices.
Thanks!
You can accomplish this by using the =QUERY() function:
=QUERY(INDEX(A2:A), "SELECT A LIMIT "&(D2-C2+1)&" OFFSET "&(C2-1))
Where C2 holds the initial index, and D2 the final one.
In case you are using this function on an output of another function, you will have to replace the A in the SELECT clause for the Col1 identifier:
=QUERY(INDEX(A2:A), "SELECT Col1 LIMIT "&(D2-C2+1)&" OFFSET "&(C2-1))
Examples