Countifs with OR criterias and ranges - google-sheets

I have 5 Columns with color options. I need to COUNT how many of them are different of Black in all options. I mean, the momment they have something different from black in one of the 5 columns, they are consider color. If not, they are considered as black. I.e, if "Red" appears in one of the 5 colums, is COLOR. I have tried to add OR inside Countifs, and using querys but it does not work. The only way I found is using a new columns with if conditions but i need to embed that in the count or query formula (I cannot add any new column in the main datasheet).[ I cannot embed pics yet so there is an screenshot.]
=if(OR(if(AND(L2<>"Black";L2<>"");"COLOR";"")="COLOR";
if(AND(M2<>"Black";M2<>"");"COLOR";"")="COLOR";
if(AND(N2<>"Black";N2<>"");"COLOR";"")="COLOR";
if(AND(O2<>"Black";O2<>"");"COLOR";"")="COLOR";
if(AND(P2<>"Black";P2<>"");"COLOR";"")="COLOR");"COLOR";"BLACK")
I have used that formula as an interface and I can count how many of them are COLOR or BLACK. It works, but I need the result without adding any additional column.
I know that any satement after "comma" in countifs is an "AND" so any range and condition is limiting needing to acomplish all the conditions. I need they work as "ORs" but I did not found a way. I would need something like:
=countifs(AND(L:L,<>"Black"L:L<>"") *OR* AND(M:M,<>"Black"M:M<>"") *OR* AND(N:N,<>"Black"N:N<>"") ...

try:
=INDEX(IF(TRIM(FLATTEN(QUERY(TRANSPOSE(L2:P),,9^9)))="",,
IF(REGEXMATCH(FLATTEN(QUERY(TRANSPOSE(L2:P),,9^9)), "(?i)black"), "BLACK", "COLOR")))
or:
=INDEX(IF(LEN(L2:L&M2:M&N2:N&O2:O&P2:P), UPPER(MAP(L2:L, M2:M, N2:N, O2:O, P2:P,
LAMBDA(L,M,N,O,P, IFS(L="BLACK",L,M="BLACK",M,N="BLACK",N,O="BLACK",O,P="BLACK",P,TRUE,"COLOR")))), ))
update:
=INDEX(QUERY(IF(TRIM(FLATTEN(QUERY(TRANSPOSE(L2:P),,9^9)))="",,
IF(REGEXMATCH(FLATTEN(QUERY(TRANSPOSE(L2:P),,9^9)), "(?i)\bblack\b"), "BLACK", "COLOR")),
"select Col1,count(Col1) where Col1 is not null group by Col1 label count(Col1)''"))

You could do it like this in I2 say
=countif(byrow(L2:P,lambda(r,countifs(r,"<>Black",r,"<>"))),">"&0)
and in J2
=countif(byrow(L2:P,lambda(r,counta(r))),">"&0)-I2
Add a sheet reference if you need the formula to be in a different sheet e.g.
=countif(byrow(Sheet6!L2:P,lambda(r,countifs(r,"<>Black",r,"<>"))),">0")
=countif(byrow(Sheet6!L2:P,lambda(r,counta(r))),">0")-A2
if in A2 and B2 of a separate sheet.
Note
If your database gets large and you get problems with Byrow/Lambda you can revert back to the more conventional Mmult:
=ArrayFormula(countif(mmult(n((L2:P<>"Black")*(L2:P<>"")),sequence(5,1,1,0)),">0"))
and
=ArrayFormula(countif(mmult(n(L2:P<>""),sequence(5,1,1,0)),">0"))-C2
assuming previous formula is in C2.

Use this formula
=ARRAYFORMULA(LAMBDA(u, {UNIQUE(u),COUNTIF(u, "="&UNIQUE(u))})
(LAMBDA(t, IFS(t=FALSE,"Color",t=TRUE,"Black"))
(REGEXMATCH(trim(LAMBDA(f, FILTER(f,f<>""))(FLATTEN(L2:P))), "(?i)black"))))
Demo

Related

In Google Sheet, how do you use SUMIFS with OR logic matching a list of items?

In order to clarify the scenario, please check the example here:
https://docs.google.com/spreadsheets/d/1E_xyPvkTIObG5JA4UfG1EQa74cFEc9QiznidJ4HSmEY/edit?usp=sharing
What I want to do here is to:
filter by date (matching a certain date)
filter by product id (matching a list of specified ids)
sum up the total
I did try to find some ideas, though none of them worked, including the solution in the article below
https://exceljet.net/formula/sumifs-with-multiple-criteria-and-or-logic
Really appriciate if someone could point me in the right direction, thanks!
use:
=QUERY({'raw data'!A2:C},
"select Col1,sum(Col3)
where Col2 matches '"&TEXTJOIN("|", 1, 'ids to match'!A2:A)&"'
group by Col1
order by Col1 desc
label sum(Col3)''")
Sumifs is different than Sumif. You also have some text mixed with numbers. Your dates are text while Column b is numeric. Try this:
=Sumifs(C:C:,A:A,"2022-09-08",B:B,82267,B:B,82602) +
Sumifs(C:C:,A:A,"2022-09-08",B:B,82267,B:B,82602B:B,82604)
As Player() points out, if you have too many products to include, using sumifs would get pretty tedious and you ought to consider using a different function (i'd use filter). However since your question was Sumifs related, that's your answer.
To illustrate how this would work with something Filter, you could do this:
=sum(filter('raw data'!C:C,('raw data'!A:A=A2)*
(isnumber(match('raw data'!B:B,'ids to match'!A:A,0)))))

How to SUMIF identical data spread out on multiple columns

I using excel to organize my cut list for a panel board. I have a table created like so, and i need help creating a formula that adds the number of pieces of panels of identical dimension and material, regardless of which panel it belongs
I have done formulas before where the datas where in a single column and there was only 1 criteria to check using UNIQUE and SUMIF formulas. I can already extract all the unique dimensions using
=UNIQUE(FLATTEN(C17:C19,E17:E19,G17:G19))
but that all that i got for now.
try:
={"Material", "Dimension", "Pcs";
QUERY({A2:C9; A2:A9, D2:E9; A2:A9, F2:G9},
"select Col1,Col2,sum(Col3) where Col1 is not null
group by Col1,Col2 label sum(Col3)''", 0)}

Detect all kinds of vegetables and fruits values within a column

I am trying to figure out i if there's a more efficient way to detect all the vegetables and fruits that exists within data contained in a certain column in this Google Sheets test Test 1. I have tried some "manual" ways with queries like adding a certain number of identified vegs & fruits like this:
=arrayformula(regexreplace(first cell in first row ;"(?i)car|mother|boxes|houses|person"; "") )
It seems to work fine, but I think it might be a more efficient way since there are many other fruits and vegs in the text and some of them even in other language, moreover I want to delete those commas left in the clean column. Any ideas?
Can try below formula-
=TEXTJOIN(", ";1;INDEX(QUERY(FLATTEN(TRIM(SPLIT(A3;",")));
"select Col1 where not Col1 matches 'machines|cold treatment|red car|houses|person|airplanes|ferrari|refrigerator'";0)))

Only apply complex arrayformula() to rows with certain value in dataset

I have a quite complext formula (i mean that is complex to me) that Tom Sharpe helped me building to aggregate values and ordering them by months in a row(you can find the details in the original post but i think you'll only need the final formula which is:
=ArrayFormula(mmult(sequence(1,counta(A2:A),1,0), if((C2:index(C:C,counta(C:C))<=eomonth(G2,sequence(1,datedif(G2,H2,"M")+1,0)))* (D2:index(D:D,counta(D:D))>=eomonth(G2,sequence(1,datedif(G2,H2,"M")+1,0))),E2:index(E:E,counta(E:E)),0)))
and here is the result -> [J1:U1]
Now, what i would need to do as the final step is to be able to group data by a certain label (John or Jane in the example) on separate rows, but mantaining the order/aggregate by month on the row. On the example, this would mean having one row with only 'John' data and below, one with 'Jane' values.
I am struggling to understand how to adapt the formula to do so.
I have tried:
Using another array to first return a list of these labels with query(unique()) or something like that, but then i struggle looping in it with the other formula.
A bit more simplistic but it could work after all: on the 1st row (the cell next to where the data will be returned) writing 'John', on row 2 'Jane' and then using filter() to only pull data that matches. The 'John, Jane' value is for the example but the real labels won't be that many, the list of labels don't need to be dynamic.
The thing with these solutions is that they work when used separately, but i can't figure out how to nest this in the first arrayformula() that Tom helped me with...As i am just beginning with the google sheets queries.
I don't really need necessarily the complete formula/code but maybe just directions or tips to visualize the way i could solve this.
Thanks to all who might contribute
With hindsight I might have done better to go down the route of using a query to calculate the sums on my previous answer rather than Mmult.
This uses the same method as before to create a 2d array of amounts vs dates (going across) and individuals (going down). Then it uses Textjoin to generate a query to group by name with the required number of columns.
=ArrayFormula(query({A2:A,if((C2:C<=eomonth(G2,sequence(1,datedif(G2,H2,"M")+1,0)))* (D2:D>=eomonth(G2,sequence(1,datedif(G2,H2,"M")+1,0))),E2:E,0)},
"select Col1,sum(Col"&textjoin("),sum(Col",,sequence(1,datedif(G2,H2,"M")+1,2))&") where Col1 is not null group by Col1"))
This is the generated query
select Col1,sum(Col2),sum(Col3),sum(Col4),sum(Col5),sum(Col6),sum(Col7),sum(Col8),sum(Col9),sum(Col10),sum(Col11),sum(Col12),sum(Col13) where Col1 is not null group by Col1
Ideally there should be an extra section saying label sum(Col2) '' etc. to suppress the 'Sum' headers.
=ArrayFormula(query({A2:A,if((C2:C<=eomonth(G2,sequence(1,datedif(G2,H2,"M")+1,0)))* (D2:D>=eomonth(G2,sequence(1,datedif(G2,H2,"M")+1,0))),E2:E,0)},
"select Col1,sum(Col"&textjoin("),sum(Col",,sequence(1,datedif(G2,H2,"M")+1,2))&") where Col1 is not null group by Col1 label sum(Col" & textjoin(") '', sum(Col",,sequence(1,datedif(G2,H2,"M")+1,2)) & ") ''"))

Google Sheets - Query - Running Total below dynamic results

Testing Sheet:
Wondering if there is a witty way to add a Total to the last row +1 of
a Query result.
See Sheet 'Lookup' for a static example of what I am asking for.
I don't know if there is a way to have a hidden column that calculates
transposed only under the last row of a query, or if there is a smart
way to work Query for this answer.
All great answers. Each on very useful in its use case.
Макс Махров gets the answer with using a query statement.
Now I was not keen on having an extra sheet to hold the totals so I added a row at the top which I can simply hide and used this formula:
query({Orders!A:E;A1:E1},"select Col1, Col3, Col4 where Col2 = '"&C3&"' order by Col4",1)
Only problem I have is trying to figure out how to add TEXT to the bottom row, it seems to only want numerical input.
How do I fix this? What am I glitching?
Thanks !
Mars
The trick is to make second query and count totals for selected product.
Plan of actions:
add new sheet with query on it, something like this: =QUERY(Orders!A:E,"select B, 0, sum(D) where B like '"&Lookup!C2&"' Group by B",0)
Prepare arrayformula which combines data in Lookup sheet: = ArrayFormula({Importrange(1),Importrange(2)}) Note that number of columns must retain the same.
Edit query so it takes Col1, Col2, Col3... instead of A, B, C...
Make word 'total' visible instead of zero. Set number format: 0;0;total Set it for range B9:B on Lookup sheet
Make Conditional Formatting with formula =and($B4 =0,isnumber($B4)) for range A4:C on Lookup sheet.
That's seems have to complete the task.
Hope it Helps!
Your Example
Working example.
Here is one way:
Put TOTAL way down in row 1000
Select the range A3:C999. Select data > filter to create filters
Select C3, set the filter to hide all blanks
A second way is to limit the query result to show only the top 8 results:
Change your query to =query(Orders!A:E, "select A, C, D where B = '"&C2&"' order by D desc limit 8",1) It will reverse-order column D (largest first), and set row limit to 8.
Change the formula of your TOTAL to =sumif(Orders!B:B,C2,Orders!D:D)
Try this formula in the column adjacent to your query:
=ArrayFormula({$C$4:offset($C$4,count($C$4:$C),0,1,1);sum($C$4:offset($C$4,count($C$4:$C),0,1,1))})
It duplicates your column of values (I haven't figured out a way around that yet) and then adds a total to the bottom of that column, and changes dynamically with the range from your query.
Here's a working version.
Interesting challenge! It got the old grey matter turning... ;)
Thanks,
Ben

Resources