Randomly sorted 1d array(google sheets) - google-sheets

How would one return a randomly sorted version of another 1d array, ignoring empty cells? For example, a 1x26(vertical) array of the alphabet in column A could be sorted into a random order in column B.

Try this
Specify your range in the lambda call once in this case A2:A57
we are using RANDARRAY with the same length of the input as a sort column in the SORT function.
=LAMBDA(rg, QUERY(SORT({rg,RANDARRAY(ROWS(rg),1)},2,1)," Select Col1 where Col1 <> '' "))
(A2:A57)

You can try with something like this. It generates a "fictional" column with random values and sort your column by them:
=SORT(FILTER(A:A,A:A<>""),BYROW(FILTER(A:A,A:A<>""),LAMBDA(e,RANDOM())),1)

You may try:
=QUERY(SORT(A1:A26,INDEX(WEEKDAY(SEQUENCE(26),3)),1),"WHERE Col1<>''")
RAND functions recalculate on every sheet change. this is more of an approach to create a static style pseudo-random array to use within sort and randomize the column A

Related

Arrayformula to calculate sum for each entry in a list

I need to automatically calculate the respective score of list of entries in a list. Basically I need something in the lines of "If letters in column F exist in column A, then sum for each entry in column A and if letter not found in F then return 0". It should be an array type of formula.
I tried both query function, which didn't work the way I wrote it, and arrayformula, but it doesn't give me sum per row.
=query(b3:g,"select sum (G) when F contains B group by B")
=arrayformula(sumifs(G4:G,B4:B,F4:F))
I know you can use a combination with mmult, but I don't know how to combine that with matching the column values for the letters in the list.
The file is listed below and is structured as following.
The score list in column A is fixed, and each month data in F-G column is posted, if the score is 0 for that month then the letter doesn't show up in the F column. I need an automatic way to calculate so I get the numbers in sheet 2.
https://docs.google.com/spreadsheets/d/1eyyqNL-LKw5F4kdDnbAPzN28jc4kWKMCJ-GAkn2yoXg/edit?usp=sharing
MAP() or BYROW() will do the trick. Try below formula-
=MAP(B3:B17,LAMBDA(x,SUMIFS(G3:G,F3:F,x)))
For >300 use-
=MAP(B3:B17,LAMBDA(x,SUMIFS(G3:G,F3:F,x,G3:G,">300")))
To make your input reference dynamic can use B3:INDEX(B3:B,COUNTA(B3:B)) as array argument or MAP() function. Try-
=MAP(B3:INDEX(B3:B,COUNTA(B3:B)),LAMBDA(x,SUMIFS(G3:G,F3:F,x)))

Counting the number of times a value appears more than once in a column AND where another conditon is met

Any help in figuring this out would be appreciated. I would like a forumla to calculate the number of times a code number appears more than once AND where type is A.
A sample set of data looks like the following:
In this case the forumla should return 1 as there is one case of a repeated code number (1) where type is (A) - first row and last row in this case.
Would the forumla be any different if I also had a third column and wanted that to be a certain value as well? Again with the test data below I would want this to return 1 in the case that I wanted to measure the number of times any code number appeared more than once where type=A and subtype=C:
.
Ihave started with the following which identifies the number of unique combinations in columns A and B, but I can't seem to add any way to only return where a particular combination appears more than once:
=COUNTUNIQUE(IFERROR(FILTER(A2:A,B2:B="A"),""))
I have tried the following but it doesn't return correctly:
=COUNTUNIQUE(IFERROR(FILTER(A2:A,B2:B="A",COUNTIF(A2:A,A2:A)>1)))
Been trying to figure this one out for a while with no success.
Thank you
You can try this (TABLE = the range corresponding to your dataset, including the header row):
=query(query(transpose(query(transpose(TABLE),,9^9)),"select Col1,count(Col1) where Col1 contains 'A' group by Col1",1),"select Col2-1 where Col2>1 label Col2-1 ''")
What we are doing is to concatenate the Code number & type columns into one using the TRANSPOSE/QUERY/TRANSPOSE...9^9 hack, querying it again to make a temporary table of each group against its count for those groups which meet the criteria, then finally subtracting one from each group count and only returning an answer if there were groups with count>1 to begin with. You will get multiple results if multiple groups satisfy the count>1 criteria.
To add the subtype column to the formula as per the second question, change TABLE to suit, then change the inner QUERY to:
"select Col1,count(Col1) where Col1 contains 'A' and Col1 contains 'c' group by Col1"
Note that the if your 'real' type & subtype categories share characters then the where/contains approach in the QUERY will fail and a different approach will be needed.
Assume that you place you data at A1:B10, what this function do is:
FILTER B1:B10 by type, which is "A" in this example, and return an array which is filtered A1:B10.
Use INDEX to extract only the 1st column, which is the code column of the filtered array, and name it 'DATA' with LAMBDA function.
Use BYROW to iterate 'DATA', and check each code with COUNTIF, if it counts more than one of this code in the filter result, return that code, else return "".
Use UNIQUE to get rid of duplicate results. (since we are looking for code which have more than 1 repeats, so the return array will sure have duplicates.)
Use query to get rid of the extry empty rows.
=QUERY(UNIQUE(
LAMBDA(DATA,
BYROW(DATA,LAMBDA(ROW,
IF(COUNTIF(DATA,ROW)>1,ROW,"")
))
)(INDEX(FILTER(A1:B10,B1:B10="A"),,1))
),"WHERE Col1 IS NOT NULL")
Just noticed that the INDEX function is not necessary, FLITER can directly returns A1:A10 according the compare results of B1:B10.
=QUERY(UNIQUE(
LAMBDA(DATA,
BYROW(DATA,LAMBDA(ROW,
IF(COUNTIF(DATA,ROW)>1,ROW,"")
))
)(FILTER(A1:A10,B1:B10="A"))
),"WHERE Col1 IS NOT NULL")

Google Sheets Query Coalesce?

is there any query syntax that woks like coalesce in google sheets?
if i have a source like pict below
the result i want is only getting id and time if status is true, but the time is only exist in one col either in check column or report column
so the result would be like this...
I tired this but doesn't work
=QUERY(A1:D4, "SELECT A, COALESCE(B, C) WHERE D = TRUE")
any ideas or workarounds?
Thanks
try:
=ARRAYFORMULA(IFERROR(SPLIT(FLATTEN(QUERY(TRANSPOSE(
ARRAY_CONSTRAIN(IF(D2:D=TRUE, {A2:A, IF(B2:C="",,"×"&B2:C), D2:D}, ), 9^9,
COLUMNS(A:C))),, 9^9)), "×")))
A very short one just for the special case of 2 columns where you know that only one of them is populated and they are dates:
=ArrayFormula(to_date(if(D2:D,B2:B+C2:C,)))
Maybe the simplest formula which behaves like coalesce would be
=iferror(if(D2,hlookup(9^9,B2:C2,1,true),))
It's just a pull-down formula but will pick up the first non-blank column from a range of columns containing numbers or dates. If the columns are all blank, it returns blank.
You can take advantage of the either or situation and concatenate the 2 columns.
=filter({A2:A,concat(B2:B,C2:C)},D2:D)
Also see local array and filter
Add a column after Status call it Time (column E), whereas each formula follows this format (assuming your table starts at A3:E)
=if(A4="","",if(B4<>"",B4,C4))
Now query A3:E like so,
=query(A3:E,"Select A,E where D=TRUE")
you can use something like this:
=QUERY(transpose(B1:H1),"Select Col1 where Col1 is not null limit 1",0)
This transposes the row into a column, queries all non-null values from that column, and then set limit 1 to return the first value. So essentially you are selecting the leftmost non-empty value from your row.
I can't take full credit for this, I must have gotten it somewhere else... but it's in one of my sheets.

Combine multi-row array into single row

I'm trying to combine the multi-row results of a QUERY into a single row.
The first result (A4:L4) should remain as-is with the following result added to the end of the previous result in the same row keeping blank values in place. The header will be removed, so that doesn't need to be considered.
I've tried nesting QUERY and FILTER but am only managing to get a single column or transpose the whole array.
=QUERY({journeySquads!A:M},"SELECT Col2,Col3,Col4,Col5,Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13 WHERE Col1='"&A1&"'",1)
You could also use flatten (no restriction on string length)
=transpose(query(flatten(query(A2:M,"select * where A='test'"))," select Col1 where Col1 is not null"))
Well, I figured it out...
=SPLIT(TEXTJOIN("| ",,QUERY({journeySquads!A2:M},"SELECT Col1,Col2,Col3,Col4,Col5,Col6,Col7,Col8,Col9,Col10,Col11,Col12,Col13 WHERE Col1='"&A1&"'",0)),"|")

Is it possible to transpose a column of text values into a single row without duplicates based on an if statement?

E.g. I have the following sheet and formula, but I only want to transpose the data if it contains a specific month, specified in A2.
try:
=TRANSPOSE(UNIQUE(FILTER(A5:A; B5:B=A2)))
You can use a query for that.
=TRANSPOSE(QUERY(A5:C, "select A where month(B)+2="&MONTH(A2)&""))
The reason we add +1 is because months in a query start from 0

Resources