2

For each of the email id, I want to get latest 10 records by timestamp. How do I get the results with arrayformula? Query function is not important as long as I can still achieve this with arrayformula. Here is the sample data: https://docs.google.com/spreadsheets/d/1YAHA02VM-5MXzVKhkxu_eODPKObpoz441mGX8lOFu5M/edit?usp=sharing

3 Answers 3

2

Try this on another sheet, row 1:

=arrayformula(query({query({Sheet1!$A:$C},"order by Col1 desc,Col2",1),{"Dupe position";countifs(query({Sheet1!$A2:$C},"select Col2 order by Col1 desc,Col2",0),query({Sheet1!$A2:$C},"select Col2 order by Col1 desc,Col2",0),row(Sheet1!$A2:$C),"<="&row(Sheet1!$A2:$C))}},"select Col1,Col2,Col3 where Col1 is not null and Col4 <= 10 order by Col1",1))

enter image description here

You can adjust the number of records found by adjusting Col4 <= 10, and also the final sort by altering order by Col1 at the end of the formula.

Explanation

This gets the data from Sheet1, sorts it by date desc then email asc: query({Sheet1!$A:$C},"order by Col1 desc,Col2",1)

enter image description here

Then to the side of this data, a COUNTIFS() is used to get the number each time an email appears in the list above (since it's sorted desc, 1 represents the most recent instance).

countifs(<EmailColumnData>,<EmailColumnData>,row(<EmailColumn>),"<="&row(<EmailColumn>))

enter image description here

enter image description here

In place of <EmailColumnData> in the COUNTIF() is: query({Sheet1!$A2:$C},"select Col2 order by Col1 desc,Col2",0)

enter image description here

In place of <EmailColumn> above, we only want the row number so we don't need the actual data. We can use: Sheet1!$A2:$C

Various {} work as arrays to bring the data together.

Eg., {a,b,c;d,e,f} would result in three columns, with a, b, c in row 1 and d, e, f in row 2. , is a new column, ; is a return for a new row.

A final query around everything gets the 3 columns we need, where the count number in col 4 is <=10, then sorts the output by Col1 (date asc).

Sign up to request clarification or add additional context in comments.

4 Comments

Thankyou, this does the job but quite complicated to follow
I've added an explanation. Also added additional 'helper' columns in your sheet on the 'Aresvik solution' tab so you can see what's going on. The formulas in the 3 yellow cells are combined in the green cell.
This a neat solution to a tricky problem and probably about as simple as it gets.
Thanks. My gut feeling is that there is probably a simpler way, but ultimately I can't see any other option than counting instances of each email.
1

On second thoughts, maybe this is bit cheeky, but this might do it ( taken from conditional rank idea )

=ArrayFormula(filter(A2:C,countifs(A2:A,">="&A2:A,B2:B,B2:B)<=10,A2:A<>""))

enter image description here

EDIT

The above assumes (because the data is time-stamped) dups shouldn't occur. If they do and the data is pre-sorted, you can use row number as a proxy for time stamp as suggested by @Aresvik.

Alternatively, you could count separately

(a) only rows with a later timestamp

plus

(b) rows with the same time stamp but with earlier (or identical) row number

=ArrayFormula(filter(A2:C,countifs(A2:A,">"&A2:A,B2:B,B2:B)+countifs(A2:A,"="&A2:A,B2:B,B2:B,row(A2:A),"<="&row(A2:A))<=10,A2:A<>""))

1 Comment

Excellent solution. Unlikely, but if the values in A are not all unique, then you could use row(), and just reference B. --> countifs(row(B2:B),">="&row(B2:B),B2:B,B2:B)
1

I have added a new sheet ("Erik Help") with the following formula in A1:

=ArrayFormula({"Submitted Time","Email","Score";SORT(SPLIT(FLATTEN(QUERY(SORT(TRANSPOSE(SPLIT(TRANSPOSE(QUERY(IF(Sheet1!B2:B=TRANSPOSE(UNIQUE(FILTER(Sheet1!B2:B,Sheet1!B2:B<>""))),Sheet1!A2:A&"|"&Sheet1!B2:B&"|"&Sheet1!C2:C,),,COUNTA(Sheet1!A2:A)))," ",0,1)),SEQUENCE(MAX(COUNTIF(Sheet1!B2:B,Sheet1!B2:B))),0),"LIMIT 10")),"|",1,0),1,0)})

The number of records is set after LIMIT.

The order is set by the final two numbers: 1,0 (meaning "sort by column 1 in reverse order," which, as currently set, is sorting in reverse order by date/time).

3 Comments

Thank you Erik! This does the job . Unfortunately, its quite complicated to follow
Do keep in mind that this forum (as well as any other forum like it) is run entirely by volunteers in our free time. Forums are designed to offer a little knowledge or a "nudge in the right direction" to many people. Most often, creating a solution for a forum takes only a few minutes and explaining is fairly straightforward. In this case, creating the solution took quite a bit more time than is typical; and explaining in detail would take even more. It seems Aresvik did choose to put in that extra time for you; but my own regular paying client load is too heavy for me to do so at this time.
understand and appreciate your contribution

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.