Google Sheets function to group and concat rows - google-sheets

Sample sheet: https://docs.google.com/spreadsheets/d/1AeP0sxDi0-3aaesUdCNTKfricIimjTMFaKO-FX9_g50/edit?usp=sharing
I am trying to find a formula that will group a table on a column and concat the values from all the rows in another column.
For example, if this is my table:
| name | value |
|-------|---------|
| one | alpha |
| two | bravo |
| three | charlie |
| one | delta |
| two | echo |
| four | foxtrot |
| two | golf |
| three | hotel |
| four | india |
This is what I want the formula to output:
| one | alpha, delta |
| two | bravo, echo, golf |
| three | charlie, hotel |
| four | foxtrot, india |
I wish I could share some formula that gets me close but I can't find anything. I thought maybe this formula but, as you can see from the sample sheet, it does not work.
=ARRAYFORMULA(JOIN(", ", TRANSPOSE(FILTER(B2:B, A2:A = {UNIQUE(A2:A)}))))
My thought was, get a unique list of values in the name column, and then use arrayformula to get a list of values in the value column where the name column equals each value in the unique list. :/

try:
=ARRAYFORMULA(REGEXREPLACE(TRIM(SPLIT(TRANSPOSE(
QUERY(QUERY({A2:A&"♦", B2:B&","},
"select max(Col2)
where Col1 !=''
group by Col2
pivot Col1"),,999^99)), "♦")), ",$", ))
or:
=ARRAYFORMULA(IFNA(VLOOKUP(UNIQUE(A2:A),
REGEXREPLACE(TRIM(SPLIT(TRANSPOSE(
QUERY(QUERY({A2:A&"♦", B2:B&","},
"select max(Col2)
where Col1 !=''
group by Col2
pivot Col1"),,999^99)), "♦")), ",$", ), {1, 2}, 0)))

Related

How to transpose & split multiple columns and repeat specific cells in a column

I am looking to transpose, split, and keep the correct corresponding Category/Reference Number.
Column A: Category / Reference Number.
Column B: Email (CSV)
| A | B | | A | B |
|001|Email1,Email2,Email3| |001|Email1|
|002|Email4,Email5,Email6| |001|Email2|
| | | |001|Email3|
| | | |002|Email4|
| | | |002|Email5|
| | | |002|Email6|
Here is another post which is similar to what I am looking to accomplish. The only difference is in this post, the OP requested that the formula duplicates data X times. Here is the formula that is used:
=ARRAYFORMULA({TRANSPOSE(SPLIT(CONCATENATE(REPT(B2:B&",", A2:A^2)), ",")),
TRANSPOSE(SPLIT(CONCATENATE(REPT(C2:C&",", A2:A)), ","))})
I have tried modifying this formula by removing the "^2", "A2:A" replacing with a COUNTIF (to determine the number of emails in each row), and keep breaking the formula.
What am I doing wrong?
Here is my sheet.
try:
=ARRAYFORMULA(TRIM(QUERY(SPLIT(FLATTEN(IF(IFERROR(SPLIT('Form Responses'!C2:C, ","))="",,
'Form Responses'!B2:B&"×"&SPLIT('Form Responses'!C2:C, ","))), "×"),
"where Col2 is not null")))

use ARRAYFORMULA to find all matching rows/values in a source table from a lookup table

I have a source table like so. As you can see, each each Lookup Value can have one or more Result.
| Lookup Value | Result |
|--------------|--------|
| a | a1 |
| a | a2 |
| a | a3 |
| b | b1 |
| b | b2 |
| c | c1 |
| c | c2 |
Then I have an input table like so:
| queries | results | | | | | |
|---------|---------|---------|---------|---------|---------|---------|
| a | ... | ... | ... | ... | ... | ... |
| c | ... | ... | ... | ... | ... | ... |
The ... for each row should be the transposed values from the lookup table. So, for example, the above table would look like this:
| queries | results | | |
|---------|---------|----|----|
| a | a1 | a2 | a3 |
| c | c1 | c2 | |
Right now I have to use multiple formulas like so:
I am trying to replace it with a single ARRAYFORMULA but it doesn't seem to work.
Is there another way to do this? Basically lookup all the matching rows from a lookup table and then transpose them?
Suppose your "Lookup Value" and "Result" data run from A1:B (with headers in A1 and B1). And suppose that your "queries" list is in D1:D (header in D1) with the "results" header in E1.
Depending on the maximum number of possible matches in B:B for any value in A:A, you could use this in E2:
=ArrayFormula(IFERROR(VLOOKUP(D2:D,QUERY(FILTER({A2:B,COUNTIFS(A2:A,A2:A,ROW(A2:A),"<="&ROW(A2:A))},A2:A<>""),"Select Col1, MAX(Col2) Group By Col1 Pivot Col3"),SEQUENCE(1,10,2),0)))
If your maximum possible matches is fewer than 10 or more than 10, feel free to edit the second argument of the SEQUENCE function accordingly.
Understand that, with such an array formula that is asked to process a range, you wouldn't be able to put other data anywhere below or to the right of your "queries and results" that you've asked the array formula to assess or fill. So if you want data under it, you'll need to limit your VLOOKUP from D2:D to, say, D2:D50 (or whatever your max queries range would be). Likewise, if that second argument of the SEQUENCE function is 10, you'll have "reserved" 10 columns (i.e., E:N) for possible results, and you won't be able to put data there or you'll "break" the array formula. That being the case, you may want to give yourself some sort of visual line of demarcation around the area you've reserved for the formula's use (e.g., change the background color of the block or place a border around it, etc.).
try:
=ARRAYFORMULA(IFERROR(VLOOKUP(D:D, SPLIT(TRANSPOSE(QUERY(TRANSPOSE(IF(ISNUMBER(
QUERY(QUERY(A:B, "select A,count(A) where A is not null group by A pivot B"), "offset 1", 0)),
QUERY(QUERY(A:B, "select A,count(A) where A is not null group by A pivot B"), "limit 0", 1),
QUERY(QUERY(A:B, "select A,count(A) where A is not null group by A pivot B"), "offset 1", 0)))
,,999^99)), " "), TRANSPOSE(ROW(INDIRECT("A2:A"&COUNTUNIQUE(B:B)))), 0)))

Counting number of columns a value appears in (Google Sheets)

I have a Google Sheet where I want to know the number of unique columns that a value appears in. For example, given the following sheet:
| A | B | C | D |
+-------+-------+-------+-------+
| Joe | Lisa | Lisa | Lisa |
| Joe | Lisa | Jenny | Lisa |
| Joe | Jenny | Jenny | John |
| Joe | Jenny | Katie | John |
| Joe | Jenny | Katie | John |
I would want something that counts Joe appearing in 1 column, Lisa appearing in 3, Jenny appearing in 2, Katie appearing in 1, and John appearing in one, i.e.
| Name | Count |
+-------+-------+
| Joe | 1 |
| Lisa | 3 |
| Jenny | 2 |
| Katie | 1 |
| John | 1 |
What's the best way to do this?
Assuming the data has no spaces in it, try:
=ArrayFormula(QUERY(SPLIT(UNIQUE(TRANSPOSE(SPLIT(JOIN(" ", QUERY(A1:D&"_"&COLUMN(A1:D1),,ROWS(A1:A)))," "))), "_"), "Select Col1, count(Col2) where Col2 > 0 group by Col1 label count(Col2)''"))
If the source data has spaces, try:
=ArrayFormula(SUBSTITUTE(QUERY(SPLIT(UNIQUE(TRANSPOSE(SPLIT(JOIN(" ", QUERY(SUBSTITUTE(A1:D, " ", "~")&"_"&COLUMN(A1:D1),,ROWS(A1:A)))," "))), "_"), "Select Col1, count(Col2) where Col2 > 0 group by Col1 label count(Col2)''"), "~", " "))
EDIT
As Tom has noticed, I've missed the task, and the correct formula is:
=QUERY(
QUERY(
{TRANSPOSE(SPLIT(TEXTJOIN("#",1,FILTER(COLUMN(A:D)*row(A:D)^0,A:A<>"")),"#")),
TRANSPOSE(SPLIT(TEXTJOIN("#",1,A:D),"#"))},
"select Col1, Col2, count(Col2) group by Col1, Col2"),
"select Col2, count(Col3) group by Col2 label Col2 'Name',count(Col3) 'Count'")
Credit: #tom-sharpe
My original formula counted max times name is in a row:
=QUERY(
QUERY(
{TRANSPOSE(SPLIT(TEXTJOIN("#",1,FILTER(COLUMN(A:D)^0*row(A:D),A:A<>"")),"#")),
TRANSPOSE(SPLIT(TEXTJOIN("#",1,A:D),"#"))},
"select Col1, Col2, count(Col2) group by Col1, Col2"),
"select Col2, max(Col3) group by Col2 label Col2 'Name'")

Select GROUP BY column without selecting the Sum() Column

Say I have searched multiple sheets with a query and gotten the following table in Google Sheets: (its nested, so it will never actually be displayed)
| Item | Amount | ID |
------------------------------
| cat | 3 | 1 |
------------------------------
| dog | 2 | 2 |
------------------------------
| dog | 4 | 2 |
------------------------------
| bird | 1 | 3 |
------------------------------
| bird | 2 | 3 |
------------------------------
| dog | 1 | 2 |
------------------------------
Obviously, If I want to get the Sum of Dogs and Birds from this table I could do something like this:
(-not exact syntax, just an example)
"SELECT Col1, sum(Col2) WHERE Col1 = 'dog' or 'bird' GROUP BY Col1 ORDER BY Sum(Col2)"
And I should get something like the following:
| Item | Amount |
---------------------
| dog | 7 |
---------------------
| bird | 3 |
---------------------
BUT - Is there a way I can return ONLY Col1 (As in still do the Grouping and ordering) so that If I was to put it side by side with a result that showed all Columns it would still line up correctly?
OK, Solved it!!! Quite Simple Really....
All I have to do is to add another layer of nesting.
SO:
=QUERY(table, "SELECT Col1, sum(Col2) WHERE Col1 = 'dog' or 'bird' GROUP BY Col1 ORDER BY Sum(Col2))"
Becomes:
=QUERY(
QUERY(table, "SELECT Col1, sum(Col2) WHERE Col1 = 'dog' or 'bird' GROUP BY Col1 ORDER BY Sum(Col2)"),
"SELECT Col1"
)
Again, Syntax not exact, but its the Logic I was after :)
:)

Counting number of occurrences in column?

What would be a good approach to calculate the number of occurrences in a spreadsheet column? Can this be done with a single array formula?
Example (column A is input, columns B and C are to be auto-generated):
| A | B | C |
+-------+-------+-------+
| Name | Name | Count |
+-------+-------+-------+
| Joe | Joe | 2 |
| Lisa | Lisa | 3 |
| Jenny | Jenny | 2 |
| Lisa | | |
| Lisa | | |
| Joe | | |
| Jenny | | |
A simpler approach to this
At the beginning of column B, type
=UNIQUE(A:A)
Then in column C, use
=COUNTIF(A:A, B1)
and copy them in all row column C.
Edit: If that doesn't work for you, try using semicolon instead of comma:
=COUNTIF(A:A; B1)
Try:
=ArrayFormula(QUERY(A:A&{"",""};"select Col1, count(Col2) where Col1 != '' group by Col1 label count(Col2) 'Count'";1))
22/07/2014 Some time in the last month, Sheets has started supporting more flexible concatenation of arrays, using an embedded array. So the solution may be shortened slightly to:
=QUERY({A:A,A:A},"select Col1, count(Col2) where Col1 != '' group by Col1 label count(Col2) 'Count'",1)
=COUNTIF(A:A;"lisa")
You can replace the criteria with cell references from Column B
Just adding some extra sorting if needed
=QUERY(A2:A,"select A, count(A) where A is not null group by A order by count(A) DESC label A 'Name', count(A) 'Count'",-1)
=arrayformula(if(isblank(B2:B),iferror(1/0),mmult(sign(B2:B=TRANSPOSE(A2:A)),A2:A)))
I got this from a good tutorial - can't remember the title - probably about using MMult
Put the following in B3 (credit to #Alexander-Ivanov for the countif condition):
={UNIQUE(A3:A),ARRAYFORMULA(COUNTIF(UNIQUE(A3:A),"=" & UNIQUE(A3:A)))}
Benefits: It only requires editing 1 cell, it includes the name filtered by uniqueness, and it is concise.
Downside: it runs the unique function 3x
To use the unique function only once, split it into 2 cells:
B3: =UNIQUE(A3:A)
C3: =ARRAYFORMULA(COUNTIF(B3:B,"=" & B3:B))

Resources