COUNTA with FILTER using multiple conditions - google-sheets

I want to count the number of companies (Col B) that have a status of 'Our System' in Col A, grouped by their postcode area (e.g., SW10, SW11 etc)
As an example, the figures in the 'On System' column reflect what the formula should result in.
A | B | C | D | E | F | G |
----------|---------|----------|---|---|----------|-----------|
Status | Name | Postcode | | | Area | On System |
----------|---------|----------|---|---|----------|-----------|
On System | ABC Ltd | SW10 4ED | | | SW10 | 1 |
----------|---------|----------|---|---|----------|-----------|
On System | XYZ Ltd | SW11 5RF | | | SW11 | 2 |
----------|---------|----------|---|---|----------|-----------|
On System | GBH Ltd | SW11 5GR | | | SW12 | 0 |
----------|---------|----------|---|---|----------|-----------|
Fresh | DEF Ltd | SW11 7GG | | | SW13 | 0 |
----------|---------|----------|---|---|----------|-----------|
Fresh | GHI Ltd | SW12 5F5 | | | SW14 | 0 |
----------|---------|----------|---|---|----------|-----------|
I've used the following formula (the below example counts companies in SW10 that are 'On System'), but with no success.
=COUNTA(IFERROR(FILTER(C:C, C:C=F3&" *", A:A="On System" )))
I'm under the impression that IFERROR removes empty results or something similar. Without it, I just get a value of 1, even if there are no SW10 rows with an On System status.
Any ideas?

To count the 'on system' with postal code SW10 try:
=sumproduct(A:A="On System", regexmatch(C:C, "SW10"))
Of course you can replace the strings with cell references.
Or -shorter- use COUNTIFS() with a wildcard (*)
=countifs(A:A, "On System", C:C, "SW10*")

Related

Google Sheets Return Any(All) Row Value(s) For MAX-GROUP Query

I am looking to return non-grouped row values from a query of a table sorted by the MAX value of a column, within a group.
DATA TABLE
| NAME | ASSET | ACTION | DATE |
|--|--|--|--|
| JOE | CAR | BOUGHT | 1/1/2020 |
| JANE | HORSE | BOUGHT | 1/1/2021 |
| JOE | HORSE | BOUGHT | 2/1/2021 |
| JANE | HORSE | SOLD | 3/1/2021 |
| JOE | CAR | SOLD | 1/1/2022 |
| JOE | CAR | BOUGHT | 2/1/2022 |
For the table above, I presented the following code.
=QUERY(A1:D5,"SELECT A,B,C,D, MAX(D) GROUP BY A,B",TRUE)
The following TARGET TABLE is output I'm looking for:
| NAME | ASSET | ACTION | DATE |
|--|--|--|--|
| JANE | HORSE | SOLD | 3/1/2021 |
| JOE | HORSE | BOUGHT | 2/1/2021 |
| JOE | CAR | BOUGHT | 2/1/2022 |
However, because 'C' is not included in the GROUP, the formula returns an error. "Unable to parse query string for Function QUERY parameter 2: ADD_COL_TO_GROUP_BY_OR_AGG: C"
If I were to omit COL C & D, "ACTION" & "DATE" from the SELECT: =QUERY(A1:D5,"SELECT A,B, MAX(D) GROUP BY A,B",TRUE) , I have the correct record rows, but am missing the STATUS.
MAX-DATE TABLE
| NAME | ASSET | max DATE |
|--|--|--|
| JANE | HORSE | 3/1/2021 |
| JOE | HORSE | 2/1/2021 |
| JOE | CAR | 2/1/2022 |
OR, when I add COL C as a "PIVIOT": =QUERY(A1:D5,"SELECT A,B, MAX(D) GROUP BY A,B PIVOT C",TRUE)I have the correct record rows, but do not have the 'current' STATUS within the record row.
PIVOT ACTION TABLE
| NAME | ASSET | BOUGHT | SOLD |
|--|--|--|--|
| JANE | HORSE | 1/1/2021 | 3/1/2021 |
| JOE | HORSE | 2/1/2021 | |
| JOE | CAR | 2/1/2022 | 1/1/2022 |
Still I have not found a method to create my TARGET TABLE.
Am I overlooking a method to include a non-grouped field into a query using MAX()? Or is it impossible within Google Sheets Query without JOIN functions?
(I hope it is obvious that I desire to apply this to a large and dynamic dataset.)
Thank you for your insight. Cheers!
It's not that flexible to work with QUERYs with its aggregation requisites and so on.
You can create a filter, by comparing column D with a "fictional" column created with BYROW: = BYROW(A2:A,LAMBDA(each,MAXIFS($D$2:$D,$A$2:$A,each,$B$2:$B,OFFSET(each,,1))))
That would look like this (I highlighted the matches and added extra rows for reference):
Then, you can set this filter (don't create this column, it's just a visualization of what I did):
=FILTER(A2:D,D2:D = BYROW(A2:A,LAMBDA(each,MAXIFS($D$2:$D,$A$2:$A,each,$B$2:$B,OFFSET(each,,1)))))
This way, you're comparing the dates with the maximum for each category

Google Spreadsheet : sort greatest values from a sort/uniq/sumifs

I use Google Spreadsheet to keep track of my wine cellar, with a simple sheet with number of bottles / name of the wine / where it's from :
+--------------+------------+-------------+
| # of bottles | Wine | Appellation |
+--------------+------------+-------------+
| 2 | Talbot | St Julien |
| 16 | Marbuzet | St Estephe |
| 1 | Terrebrune | Bandol |
| 10 | Madiniere | Cote Rotie |
+--------------+------------+-------------+
I'd like to get a roundup of appellation I have the most, sorted by number of bottles, eg:
+--------------+-------------+
| # of bottles | Appellation |
+--------------+-------------+
| 16 | St Estephe |
| 10 | Cote Rotie |
| ... | ... |
+--------------+-------------+
I know how to get the sorted list of appellations (=sort(UNIQUE($C$2:$C$999) with wine origin in column C) and the matching number of bottles (=SUMIFS(A:A,C:C,<cell with appellation name>), but I'm stuck at sorting by the number of bottles instead.
With QUERY
=QUERY(A:C,"select sum(A),C group by C order by sum(A) desc",1)
To rename the header:
=QUERY(A:C,"select sum(A),C group by C order by sum(A) desc label sum(A) '# of bottles'",1)
With SORT and SUMIF
=ArrayFormula(SORT({SUMIF(C:C,UNIQUE(C2:C),A:A),UNIQUE(C2:C)},1,FALSE))

Try to match string in column and print matching column name

I am trying to build an expense dashboard in google sheets for my personal use.
I have data that I will pull from my receipts like so:
First sheet: "Expenses Feb 18"
+------------+--------+--------+
| Item | Amount | Type |
+------------+--------+--------+
| Tomatoes | 2.39 | veggie |
| Joghurt | 1.45 | dairy |
| mozzarella | 1.99 | dairy |
| macadamia | 4.59 | nuts |
+------------+--------+--------+
Second table: "Categories"
+------------+----------+-----------+---------------+
| dairy | veggie | nuts | uncategorised |
+------------+----------+-----------+---------------+
| joghurt | tomatoes | macadamia | a |
| mozzarella | cucumber | pecan | b |
| feta | | | c |
| | | | d-z |
| | | | 0-9 |
| | | | - |
| | | | _ |
+------------+----------+-----------+---------------+
I want to automatically fill out the type column based on the item name.
So far I have a regex that is able to match an item. It will print the matched string. But what I need is the column name (header). And it has to be able to loop through the columns. This only works for a single column.
=REGEXEXTRACT(C11, JOIN("|", INDIRECT("Categories!A1:A"&COUNTA(Categories!A:A))))
The second table is not a desirable way to enter data. Data should be entered preferably with more rows than columns ( not in a pivoted manner).
=ARRAYFORMULA(CONCATENATE(IF(A16=$C$24:$E$25,C$23:E$23,)))
A16 : 🍅
C24:E25: Category table
C23:E23: Category header.

SUMPRODUCT with wildcard

I have the SUMPRODUCT working with hardcoded values however I want to use a wild card for the B clomun in my example.
Here is my data
+----------+----------+-----------+
| A COLUMN | B COLUMN | C COLUMN |
+----------+----------+-----------+
| Status | Fruit | Quanitity |
| | | |
| Fresh | Apple | 6 |
| | | |
| Fresh | Apricot | 7 |
| | | |
| Stale | Apple | 4 |
+----------+----------+-----------+
I would like to match Fresh, AP* and then sum the matches form Column C.
I have the following
=SUMPRODUCT(--($B$2:$B$840="AP*"),--($A$2:$A$840="Fresh"),$C$2:$C$840)
Working code with the Wildcard but the count is off
=SUMPRODUCT(ISNUMBER(SEARCH"AP",$B$2:$B$840,1))*($A$2:$A$840="Fresh")*($C$2:$C$840))
The SUMPRODUCT() function does not support wildcards within an array-type expression. The same result can be achieved with:
=SUMPRODUCT((A2:A1000="Fresh")*(LEFT(B2:B1000,2)="Ap")*(C2:C1000))

Count occurrences of words from multiple columns

I have a spreadsheet like this, where the values A-E are the same options coming from a form:
+------+------+------+
| Opt1 | Opt2 | Opt3 |
+------+------+------+
| A | A | B |
| B | C | A |
| C | C | B |
| A | E | C |
| D | B | E |
| B | E | D |
+------+------+------+
I want to make a ranking, showing the most chosen options for each option. I already have this, where Rank is the ranking of the option and number is the count of the option:
+------+------+------+
| Rank | Opt1 | Numb |
+------+------+------+
| 1 | A | 2 |
| 1 | B | 2 |
| 3 | C | 1 |
| 3 | D | 1 |
+------+------+------+ (I have 3 of these, one for each option)
I want to do now a summary of the 3 options, making the same ranking but joining the options. It would be something like:
+------+------+------+
| Rank |Opt123| Numb |
+------+------+------+
| 1 | B | 5 |
| 2 | A | 4 |
| 2 | C | 4 |
| 4 | E | 3 |
| 5 | D | 2 |
+------+------+------+
The easiest way to do this would be getting the data from the three ranking tables or from the original three data columns?
And how would I do this?
I already have the formula to get the names of the options, the count and ranking, but I don't know how to make them work with multiple columns.
What I have (the F column is one of the data columns):
Column B on another sheet:
=SORT(UNIQUE(FILTER('Form Responses'!F2:F;NOT(ISBLANK('Form Responses'!F2:F)))); RANK(COUNTIF('Form Responses'!F2:F; UNIQUE(FILTER('Form Responses'!F2:F;NOT(ISBLANK('Form Responses'!F2:F))))); COUNTIF('Form Responses'!F2:F; UNIQUE(FILTER('Form Responses'!F2:F;NOT(ISBLANK('Form Responses'!F2:F))))); TRUE); FALSE)
Column C:
=ArrayFormula(COUNTIF('Form Responses'!F2:F; FILTER(B2:B;NOT(ISBLANK(B2:B)))))
Column A:
=ARRAYFORMULA(SORT(RANK(FILTER(C2:C;NOT(ISBLANK(C2:C))); FILTER(C2:C;NOT(ISBLANK(C2:C))))))
Edited:
Merge cols:
=TRANSPOSE(split(join(",",D2:D,E2:E),","))
merges 2 cols, not very clean, but works. (Same as here Stacking multiple columns on to one?)
Full formula:
=SORT(UNIQUE(FILTER(TRANSPOSE(split(join(",",D2:D,E2:E),","));NOT(ISBLANK(TRANSPOSE(split(join(",",D2:D,E2:E),",")))))); RANK(COUNTIF(TRANSPOSE(split(join(",",D2:D,E2:E),",")); UNIQUE(FILTER(TRANSPOSE(split(join(",",D2:D,E2:E),","));NOT(ISBLANK(TRANSPOSE(split(join(",",D2:D,E2:E),","))))))); COUNTIF(TRANSPOSE(split(join(",",D2:D,E2:E),",")); UNIQUE(FILTER(TRANSPOSE(split(join(",",D2:D,E2:E),","));NOT(ISBLANK(TRANSPOSE(split(join(",",D2:D,E2:E),","))))))); TRUE); FALSE)
The transpose could be done after the sort.

Resources