Excel sort table value and return row names of the 5 largest rows - excel

As stated in the title, the table has two columns, one for row names and the other is for values, I just want to return the row names and values of the 5 rows with the largest value accordingly back to another range of cells. (It will be better if I don't have to operate the table)
Thank you very much!
for example the table is like:
Johnny 1
Harry 2
Jessie 3
Luke 4
Mary 2
Lucy 1
Peter 5
Basically I would like the ouput to be
Peter 5
Luke 4
Jessie 3
Harry 2
Mary 2

The fifth biggest number you get like this
=LARGE($B$1:$B$10;5)
and then you will find the row number of this value with MATCH and use this in INDEX to get the text value
=INDEX($A$1:$A$10;MATCH(LARGE($B$1:$B$10;5);$B$1:$B$10))
Now this will not work, if you have values appearing twice. Then an additional column could help or some more complicated trick for the MATCH part, like
MATCH(LARGE(B1:B10-ROW(B1:B10)/1000;1);B1:B10-ROW(B1:B10)/1000;0)
And then you have to make an array function out of the formula but pressing CTRL+SHIFT+ENTER not only ENTER. Then {} will be added around the formula.

Related

Get multiple values in a single cell with array formula

I'm trying to get an array formula to get the multiple results in a single cell. Is that possible?
For example below, I'd like to show in D2 all the names in column B corresponding to rows for values less than 4 in column A.
My current attempt below:
A C
2 Jane
3 John
6 Thomas
1 Michael
2 Mary
7 Jason
3 Gloria
1 Andrea
=CONCAT(INDEX($B$2:$B$9,IF($A$2:$A$9<4,$B$2:$B$9)))
My desired result would be:
Jane, Michael, Mary, Andrea
You need FILTER() then TEXTJOIN().
=TEXTJOIN(", ",TRUE,FILTER(B2:B9,A2:A9<4))

How to SELECT N values ABOVE and BELOW from specific value

If I have a table:
Column A
Column B
Column C
1
Jane
10
2
Stewe
9
3
John
8
4
Mike
7
5
Luke
6
6
Andrew
5
7
Carl
4
8
Sasha
3
9
Ariel
2
10
Carol
1
I would like to SELECT 3 rows above and below WHERE Column B = someValue .
IF query SELECT * WHERE Column B = "Andrew" result should look like:
Column A
Column B
Column C
3
John
8
4
Mike
7
5
Luke
6
6
Andrew
5
7
Carl
4
8
Sasha
3
9
Ariel
2
I know how to select one row, but cant understand how to select such range.
Thanks for ideas!
You can limit and offset inside your QUERY():
=QUERY(A1:C,"limit "&2+MIN(5,MATCH(D1,B:B,0))&" offset "&MAX(0,MATCH(D1,B:B,0)-5))
Well, this was fun...
If 3 above or below are not available then blank... rolling data around is a different proposition.
Below the image is the list of formulae used.
So, per cell not including the data validation that is based on cells B2:B11
A14 and dragged down:
=IFERROR(INDEX($A$2:$A$11,MATCH(B14,$B$2:$B$11,0)),"")
C14 and dragged down:
=IFERROR(INDEX($C$2:$C$11,MATCH(B14,$B$2:$B$11,0)),"")
Cells B14 through B20:
=IFERROR(IF(MATCH(B$17,$B$2:$B$11,0)=3,NA(),INDEX($B$2:$B$11,MATCH(B$17,$B$2:$B$11,0)-3)),"")
=IFERROR(IF(MATCH(B$17,$B$2:$B$11,0)=2,NA(),INDEX($B$2:$B$11,MATCH(B$17,$B$2:$B$11,0)-2)),"")
=IFERROR(IF(MATCH(B$17,$B$2:$B$11,0)=1,NA(),INDEX($B$2:$B$11,MATCH(B$17,$B$2:$B$11,0)-1)),"")
=E2
=IFERROR(INDEX($B$2:$B$11,MATCH(B$17,$B$2:$B$11,0)+1),"")
=IFERROR(INDEX($B$2:$B$11,MATCH(B$17,$B$2:$B$11,0)+2),"")
=IFERROR(INDEX($B$2:$B$11,MATCH(B$17,$B$2:$B$11,0)+3),"")
In Excel 365, you could try:
=INDEX(A:C,MAX(2,MATCH(D2,B:B,0)-3),0):INDEX(A:C,MIN(COUNTA(B:B),MATCH(D2,B:B,0)+3),0)
In Google sheets, on the other hand, the formula would be:
=INDEX(A:C,MAX(2,MATCH(D2,B:B,0)-3),0):INDEX(A:C,MIN(COUNTA(B:B),MATCH(D2,B:B,0)+3),0)
(spot the difference).
Excel
Google Sheets
This should produce what you want in all cases:
=IFERROR(FILTER(A2:C,B2:B<>"",ROW(A2:A)>=VLOOKUP("Andrew",{B2:B,ROW(B2:B)},2,FALSE)-3,ROW(A2:A)<=VLOOKUP("Andrew",{B2:B,ROW(B2:B)},2,FALSE)+3))
Of course, you can replace the two instances of "Andrew" with a cell reference (one where you type a changeable name).
This just looks up the row in a curly-bracket array formed from the names and row numbers and uses FILTER to keep results to rows between +/-3 rows of where the target name is found. If you choose the first name (or any other name), you won't get an error; because even if the target name were on Row 1 and the formula goes looking for anything "greater than or equal to 1 minus 3, all rows will be greater than a negative number. Same on the high end. You just won't get a full seven names if there aren't at least three other rows prior to or after the target row.
this not the best solution but it will work , you can use a helper column 'D' that contains the following formula =if(countif(INDIRECT("B"&ROW()+3&":"&"B"&ROW()-3),"Andrew")>0,TRUE,FASLE)
and u can query from here like this SELECT * WHERE Column D = TRUE

Highlight duplicates, ignoring same row

I have a worksheet containing names in 2 dimensions. Each row represents a general location, every other column represents a specific slot in that location (each location has the same number of available slots), alternating with a parameter belonging to that name. There is a name in each cell. Here's a simplified version to show what my data looks like:
Location 0 ( ) 1 ( ) 2 ( ) 3 ( )
Garden Tim 3 Pete 1 Oscar 1 Lucy 2
Room1 Lucy 1 Tim 1 Lucy 5 Anna 1
Kitchen Frank 1 Frank 2 Frank 1 Lucy 1
What I want to achieve is to highlight (using conditional formatting, I'm open to alternative methods though) each entry that also appears in another row. So basically it should highlight duplicates, but ignore duplicates in the same row. The first row and column are to be excluded from the operation (no big deal, I just don't select them), as are the parameter columns (this is a big deal, as this pretty much breaks everything I've tried including the first answers given). I have access to the entire meaningful data area (all cells containing names) by the name "entries" and all meaningful entries in a given row by the name "row".
In my example above, all Tim and Lucy entries should be highlighted because they have duplicates in other rows. Pete, Oscar and Anna are unique, so they're not highlighted. Frank, while having duplicates, only has them in the same row, no other row contains Frank, so he should not be highlighted. Excel's own highlight duplicates would highlight Frank, while handling all the others correctly.
How can I modify the conditional formatting's behaviour to ignore duplicates in the same row?
The following formula (thanks to #Dave) resulted in a #VALUE! error:
=(COUNTIF(entries;B2)-COUNTIF(row;B2))>0
or you could just do (no need for an IF() when used in Conditional Formatting Formula box:
=COUNTIF($B$2:$I$4;$B2)>COUNTIF($B2:$I2;$B2)
This single formula should prevent the parameters from being highlighted
select B2:I2 and
put this (exactly) in the conditional formatting box: =AND(NOT(ISNUMBER(B2));COUNTIF($B$2:$I$4;B2)>COUNTIF($B2:$I2;B2))
Something like this:
=(COUNTIF($B$2:$E$4,B2)-COUNTIF($B2:$E2,B2))>0
The first countif counts all instances in the range, the second one subtracts the count of entries in the row. If there are more instances in the entire range than in the row it returns true

SUMIF for first 5 cells meeting criteria

Simple Excel Table such as
A B
1 John 5
2 John 7
3 John 9
4 Jill 25
5 John 21
6 John 22
7 Jill 50
8 John 100
9 John 2000
10 Jack 4
Using SUMIF, we can return the total assigned to John.
=SUMIF(A:A,"John",B:B)
Is there a way to return only the first 5 values that match the criteria? Or is there a way to return the 5 smallest values for John? Either would work.
Oh well. I'll go ahead and presume that you have Excel 2010 or later.
With e.g. "John" in D1, enter this formula in E1:
=SUMIFS($B$1:$B$10,$A$1:$A$10,D1,$B$1:$B$10,"<="&AGGREGATE(15,6,$B$1:$B$10/($A$1:$A$10=D1),5))
Copy down to give similar results for names in D2, D3, etc.
Regards
Formula:
=IF(COUNTIF($A$1:A1,A1)<=5,SUMIF($A$1:A1,A1,$B$1:B1),"")
The last value shown for each person will be the sum of the first (up to)5 values for that person. Just copy and paste values then sort.
Your sample data would show the same result for either the first 5 or lowest 5 as John's numbers are in ascending order. If that is not always the case or if you need to provide compatibility to versions of Excel earlier than 2010 I would offer the following. Note that in my sample image, I've resorted the numerical values in descending order to illustrate the difference.
For John's first 5 values (E2 in the sample image):
=SUM(INDEX(($B$2:$B$11)*($A$2:$A$11=D2)*(ROW($1:$10)<=SMALL(INDEX(ROW($1:$10)+($A$2:$A$11<>D2)*1E+99,,), 5)),,))
For John's lowest 5 values (F2 in the sample image):
=SUMPRODUCT(SMALL(INDEX(($B$2:$B$11)+($A$2:$A$11<>D2)*1E+99,,),ROW($1:$5)))
These are standard formulas. Any array processing is supplied by INDEX and/or SUMPRODUCT. Ctrl+Shift+Enter is not required. Some form of error control may be necessary when there are less than 5 matching values; a simple IF(COUNTIF(), <formula>) would suffice. When transcribing these type of formulas it is important to note that ROW(1:10) is the position within B2:B11 or A2:A11, not the actual row on the worksheet.
 
                  
In C1 enter:
=IF(A1="John",1,0)
In C2 enter:
=IF(A2="John",1+MAX($C$1:C1),0)
and copy down. Then use:
=SUMPRODUCT((A:A="John")*(B:B)*(C:C<6))
.
Assuming John in D1 you can get the sum of the 5 smallest values for John with this array formula
=SUM(SMALL(IF(A$1:A$100=D1,B$1:B$100),{1,2,3,4,5}))
confirm with CTRL+SHIFT+ENTER and copy down for to work for all names in the list

Return value of last match

I need a formula to return the value of Data for the last match of "Text". Row number is also acceptable. Macro is NOT acceptable. Name column is unsorted and cannot be sorted!
Only column "Name" is used as lookup value. I would rather use a/multiple helper column(s) instead of an array formula.
Row Name Data
1 Joe 10
2 Tom 20
3 Eva 30
4 Adam 40
5 Tom 21
LARGE only works with numbers, and VLOOKUP only returns the first match. LOOKUP only works sometimes, so its out too.
So if I wanted the last match for "Tom" then it should return "21".
Array formulas could be avoided with a helper column.
Suppose to have in F1 the name to match (i.e. Tom)
In the helper column row C2 enter
=IF(A2<>$F$1,0,row())
Then copy the formulas along your data.
Now the column C contains 0 for the unmatched names and the row number for the matched ones. Maxing the column yield the row of the solution.
Now the result is simple a matter of using the correct offset with the function offset:
=OFFSET(B1,max(C:C)-1,0)
PS: my copy of excel is in italian, so I can't test this english translaction of the formulas.
I think it's the easiest way to make it.
=LOOKUP("Tom";A2:B7)
Create a column with an array formula (enter it with Ctrl+Shift+Enter):
=VLOOKUP(MAX(IF($B$2:$B$6=B2, $A$2:A$6, 0)), $A$2:$C$6, 3, FALSE)
To make sure you did it right, click on the cell, and the formula should be shown encased in curly brackets ({}).
Note: This assumes that "Row" is in A1.
I have come up with a solution, but it requires that numbers in Data are concurrent, like so
Name Data
Joe 1
Tom 1
Eva 1
Adam 1
Tom 2
Tom 3
Eva 2
But thats okay, since that my data looks like that anyway. So if Name is used before then it must be the old highest +1 aka concurrent.
Name is A1 and Data is B1, and this formula goes into C2:
FLOOR(SQRT(2*SUMIF(A2:A7,A2,B2:B7)),1)

Resources