How to get name and top N values from range - google-sheets

I'm trying to create a small leaderboard with columns of names and scores in the following format:
Name 1, Name 2
Value, Value
Value, Value
Value, Value
I would like to grab the N largest values,and pair them with their name like so:
Name 2, Value 1st Largest
Name 1, Value 2nd Largest
Name 2, Value 3rd Largest
I've found that the command LARGE allows you to grab the nth largest value in a selected range, but I can't figure out how to pair that with the name at the top of the column. I suspect I can use Query but I am unsure how I would form that command.

Assuming your Name 1 and Name 2 are in columns A and B like this:
Try this in cell D1:
=arrayformula(query({array_constrain({if(A2:A<>"",A$1&", "&A2:A,),A2:A},MAX(IF(A:B<>"",ROW(A:A))),2);if(B2:B<>"",B$1&", "&B2:B,),B2:B},"select Col1 order by Col2 desc limit 3",0))
Notes
As long as there is a value in A:A, the array {} gets the value in cell A1, then a comma then the value in each row of column A, then a new column with just the value in each row of column A:
{if(A2:A<>"",A$1&", "&A2:A,),A2:A}
Then an ARRAY_CONSTRAIN fixes the result to as many rows as there is data in column A: MAX(IF(A:B<>"",ROW(A:A))), and 2 columns.
As part of the array, ; return the data, then adds if(B2:B<>"",B$1&", "&B2:B,),B2:B which is the value in cell B1, then a comma then the value in each row of column B, then a new column with just the value in each row of column B.
The date therefore looks like this:
Name1, 202 202
Name1, 564 564
Name1, 269 269
Name1, 33 33
Name1, 455 455
Name1, 32 32
Name1, 9870 9870
Name2, 65 65
Name2, 322 322
Name2, 4566 4566
Name2, 422 422
Name2, 45 45
Name2, 5633 5633
A QUERY around this data select Col1 and orders by Col2 descending. The results in the query are limited to 3 records.
The ARRAYFORMULA works down the sheet.
Alternative formula
If you want the results in two columns, then use this:
=arrayformula(query({array_constrain({if(A2:A<>"",A$1,),A2:A},max(counta(A:A),MAX(IF(A:B<>"",ROW(A:B)))),2);if(B2:B<>"",B$1,),B2:B},"order by Col2 desc limit 3",0))

Related

How do I sum the cells of one column based on unique duplicate rows of other columns?

I need column D summed wherever column A-C are identical. Column E is what I want the output to look like. I am only using google sheet functions right now and have not learned how to write script. This formula is the closest I've gotten.
=SUM(filter(D:D;COUNTIF(A2:A&B:B&C:C;A2:A&B:B&C:C)>1))
However, it does not distinguish between different text strings only sums any duplicate.
Thanks for any help!
A
B
C
D
E
papaya
10/10/2022
500
42
42
papaya
15/12/2022
550
30
59
papaya
15/12/2022
550
29
59
Pineapple
16/11/2022
400
55
55
Pineapple
09/11/2022
400
63
78
Pineapple
09/11/2022
400
15
78
use:
=QUERY(A:E; "select A,B,C,sum(D) where D is not null group by A,B,C label sum(D)''")
update
use in M2:
=INDEX(LAMBDA(bc; g; i; IFERROR(g/VLOOKUP(bc; QUERY({bc\i*1};
"select Col1,sum(Col2) where Col2 > 0 group by Col1 label sum(Col2)''"); 2; )))
(B2:B&C2:C; G2:G; I2:I))

How to Divide the Sum of a Range by each Row from the Range in Google Sheets with Query?

I am using Query to pull Columns A and B from another sheet like this:
Query(Tank_List!A1:M716, "select A,E, SUM (E) Where B=1 Group by A,E",1)
Column A
Column B
Column C
Item 1
9240
9240
Item 2
11843
11843
Item 3
6372
6372
Item 4
8320
8320
Item 5
16365
16365
Item 6
1234
1234
Instead of returning the actual Sum of ColB (The SUM of the Range of numbers from ColB) it returns just a copy of ColB on it's line.
I've tried several ways but the issue is SUM returns a single total for ColB or as above, the SUM of just the Row.
I am hoping for something like this:
Column A
Column B
Column C
Column D
Item 1
9240
53374
ColC/ColB
Item 2
11843
53374
ColC/ColB
Item 3
6372
53374
ColC/ColB
Item 4
8320
53374
ColC/ColB
Item 5
16365
53374
ColC/ColB
Item 6
1234
53374
ColC/ColB
Where I can do equations based on the original range numbers and the total SUM of that range. I imagine the answer will have to do with ArrayFormula, but I could not make it work myself.
It's hard to tell exactly what you want as you have columns not listed, but it would probably be easist to just grab the number using a regular sum value, then parse it into your query. I didn't duplicate your sheet, but used the below sample data and this formula:
=Query(A:B, "Select A, Sum(B), "&sum(B:B)&",SUM (B)/"&sum(B:B)&" where A is not null Group by A",1)
You can see the output pasted in cell E1 which has the division done in column G.
Your Sample Data
Column A
Column B
Item 1
9240
Item 2
11843
Item 3
6372
Item 4
8320
Item 5
16365
Item 6
1234
Use FILTER instead QUERY:
=ARRAYFORMULA({FILTER({Tank_List!A1:A,Tank_List!E1:E},Tank_List!B1:B=1),FILTER(Tank_List!E1:E,Tank_List!B1:B=1)/SUMIF(Tank_List!B1:B,1,Tank_List!E1:E)})
Retrieve columns A and E in the first part of array, then for each value in E that I divide for a sum with SUMIF.

How to sort data into a table from columns with duplicate names with different information for each row

So I have this data:
Name Post ID
CASTILLO, FIONA SN 32
ALDERETE, ROSABEL AN 56
ALDERETE, ROSABEL GN 11
ALMONARES, OLIVER SN 3
ALMONARES, OLIVER GN 2
ALVAREZ, JR., EDUARDO GN 36
ALVAREZ, JR., EDUARDO AN 1
ARELLANO, DONNALYN SN 36
ARELLANO, DONNALYN AN 63
ARELLANO, DONNALYN GN 7
CASTILLO, FIONA SN 1
CASTILLO, FIONA SN 1
DE LEON, AMABEL GN 1
DENNISON, GRETCHEN AN 11
DENNISON, GRETCHEN AN 26
DENNISON, GRETCHEN SN 5
And I want to create a table where the rows are the unique names of the people (not duplicated) and the column headings are Name, SN, AN, GN, and the values inside are the corresponding numbers. I know how to create this using a pivot table But which function would separate the data once the table is created.
The data above are cells A2:C16 and my desired output is C2:C9 would be the names, C1 is the name header, D1 is the SN header, E1 is the AN header, and F1 is the GN header. The values occupying the table would be the ID that corresponds with each person.
try:
=QUERY({A1:C}; "select Col1,max(Col3) where Col1 is not null group by Col1 pivot Col2")
you can change max for min, sum, avg or count if you need so

How to add and highlight rows on input of particular column in Google Sheet

In the attached google sheet.
Google Sheet - https://docs.google.com/spreadsheets/d/1KxqaI-GYWur0Knt_bShI0GURucqU_cawu_sCoG_8Xlc/edit?usp=sharing
I need to execute the following two operations on input.
Add same number of rows against which ID if any user put the value as 1 in column K.
For Example, If I input 1 in column K for ID = ID_3 which has 5 rows, I want to append that five rows below where the last instance of ID_3 and in appended rows all the values should be the same as ID_3 except column C which will now be ID_3_Append, column K and O which should be blank for appended rows.
If someone input value as 1 in column M, We need to check for which ID it belongs and look for that id in column E, F, and G and highlight rows with red color if ID against which user has provided input as 1 is available in column E, F, and G.
If someone adds value as 1 in change type, I need to update the column B to I in the Test_1 sheet from Put_list but want to keep the Mark Status for common ID (if it has any Mark Status) between earlier Test_1andPut_list` unchanged. Also, we need to highlight the dependent rows accordingly.
Once we update column B to I we need to change the Name from 'Call' to 'Put'.
use:
=ARRAYFORMULA(QUERY({QUERY({Test_1!A:O;
IFERROR(IF(IFNA(VLOOKUP(Test_1!C2:C, SORT({Test_1!C2:C, Test_1!K2:K}, 2, 0), 2, 0))=1,
{Test_1!A2:A, Test_1!B2:B, Test_1!C2:C&"_Append", Test_1!D2:J, Test_1!X2:X*0,
Test_1!L2:L, Test_1!X2:Y*0, Test_1!O2:O},
{"","","","","","","","","","","","","","",""}),
{"","","","","","","","","","","","","","",""})},
"where Col1 is not null and not Col3 matches '"&
TEXTJOIN("|", 1, "×", UNIQUE(IF(IFNA(VLOOKUP(Test_1!C2:C,
SORT({Test_1!C2:C, Test_1!N2:N}, 2, 0), 2, 0))=1, Test_1!C2:C, )))&"' order by Col3", 1);
IF(LEN(TEXTJOIN("|", 1,
UNIQUE(IF(IFNA(VLOOKUP(Test_1!C2:C, SORT({Test_1!C2:C, Test_1!N2:N}, 2, 0), 2, 0))=1, Test_1!C2:C, ))))>0,
QUERY({IF(Put_list!A2:A="",,IFERROR(Put_list!A2:A*1, "Put")), Put_list!A2:H,
IFNA(VLOOKUP(Put_list!B2:B&"♦"&COUNTIFS(Put_list!B2:B, Put_list!B2:B, ROW(Put_list!B2:B), "<="&ROW(Put_list!B2:B)),
{Test_1!C2:C&"♦"&COUNTIFS(Test_1!C2:C, Test_1!C2:C, ROW(Test_1!C2:C), "<="&ROW(Test_1!C2:C)), Test_1!J2:O}, {2,3,4,5,6,7}, 0))},
"where Col3 matches '"&TEXTJOIN("|", 1,
UNIQUE(IF(IFNA(VLOOKUP(Test_1!C2:C, SORT({Test_1!C2:C, Test_1!N2:N}, 2, 0), 2, 0))=1, Test_1!C2:C, )),
UNIQUE(IF(IFNA(VLOOKUP(Test_1!C2:C, SORT({Test_1!C2:C, Test_1!N2:N}, 2, 0), 2, 0))=1, Test_1!C2:C&".+", )))&"'"),
{"","","","","","","","","","","","","","",""})}, "where Col1 is not null order by Col3", 1))
transcript:
we start with array of {C, K} columns that we sort based on K column so if K column contains 1 then it will be moved up
this is convinient for VLOOKUP coz it will always look for 1st unique value eg. exactly wat we need if our array is sorted
so we vlookup C values to match our sorted array and return column K for all same IDs 2 stands for 2nd column from sorted array and 0 stands for "exact match"
if no match is found vlookup will output #N/A error so we wrap it into IFNA - then if no match is found vlookup will output empty rows
then we put this into IF statement... if our vlookup outputs 1, we output our columns (again in {array} form
if our vlookup outputs 0 then we output array of 15 empty cells in a row {"","","", .....} this is because we use arrays {} and all ranges in arrays needs to be of same size
our table has 15 columns so if some error would happen the we would get error in one single cell aganist our 15 columns
this way we avoid "array_literal error" having {15 columns; 15 cells in a row which is also 15 columns}
; semicolon puts these two arrays/ranges under each other while , comma will put then next to each other
so if vlookup results in 1 then we assemble our array with ranges... A, B columns are same then we append to C column the phrase "_Append" with &
D:J columns are same... then we force column of zeros by multipling random empty column (X) with 0 etc.
then again we use {"","","", ....} within IFERROR to deal with any possible error at this point
next we put all written above under our whole range Test_1!A:O and we wrap it into QUERY where we state to filter out all empty rows where Col1 is empty and 2nd condition of our query states
that Col3 of our array cant match our regex pattern which we assemble with TEXTJOIN formula
| stands for "or" in regex. 1 in textjoin means "all non empty cells". then we use × (unique symbol) in case textjoin would output empty cell on its own resulting in some error somewhere
again we perform same vlookup, same ifna and same IF but now we output only C column and we are interested only into UNIQUE values
then within the query we sort / order by Col3 our table and 1 at the end stands for "header rows"
This may answer the second part of your question.
Select the range of rows you want the red conditional formatting on, for example A2:A12 in your sample sheet.
Select Format - Conditional Formatting, verify the range, and apply a custom formula, as follows:
=OR(
IF($E2<>"NA",IFERROR(MATCH($E2,FILTER($C$1:$C$12,$M$1:$M$12=1),0)),0),
IF($F2<>"NA",IFERROR(MATCH($F2,FILTER($C$1:$C$12,$M$1:$M$12=1),0)),0),
IF($G2<>"NA",IFERROR(MATCH($G2,FILTER($C$1:$C$12,$M$1:$M$12=1),0)),0))
The FILTER pulls which IDs have a "1" in the update column, ColM.
MATCH looks to see if the ID in the Dependency column is in that filtered list.
The IFERROR sets the result to zero if no match.
And the initial IF, filters out the NA values in the Dependency column.
This logic is replicated for each Dependency column, so three IFs.
And the whole thing is wrapped in an OR function, so if any of the Dependency columns have a matching ID, the whole row is flagged for red.
I've applied this in a tab added to your sheet, Test_1-GK.
Let me know if this helps.
I'm afraid I didn't understand the first part of your question. I got confused with this bit:
I want to append that five rows below where the last instance of ID_3 and in appended rows all the values should be same as ID_3 except column C which will be now be ID_3_Append, column K and O which should be blank for appended rows.

How to change specific values to be a range instead

I have a list of values in Google Sheets for example:
10
14
36
43
64
110
92
103
and I want to change it to a range of
0-20, 21-40, 41-80, 81-120
so that it outputs
2
1
2
3
(two values in the range 0-20, one value in the 21-40 range, two values in the 41-80 range, and three values in the 81-120 range.)
You can do it in one step with the Frequency function FREQUENCY(data, classes):
=frequency(A2:A10,{20,40,80,120})
Note that Frequency creates one count per class, plus an extra count for values which exceed the highest class value. You can suppress this if you want to, but it could be a useful check for outliers.
=QUERY(ARRAYFORMULA({A1:A, IF(LEN(A1:A),
IFERROR(VLOOKUP(A1:A, {{0, "0-20" };
{21, "21-40" };
{41, "41-80" };
{81, "81-120" }}, 2), ),)}),
"select Col2, count(Col2)
where Col2 !=''
group by Col2
label count(Col2)''")
alternatives: https://webapps.stackexchange.com/a/123741/186471

Resources