I've got data like this:
A | B
-----------------------
Date | Data
30/06/2015 | 1.2
01/07/2015 | 2
01/07/2015 | 3
02/07/2015 | 2
02/07/2015 | 3
And I write a simple query like this:
=query(A:B; "select YEAR(A) || ' ' || month(A), SUM(B)
group by YEAR(A), month(A)")
But I've got a "Value Error", so I write this
=query(A:B; "select YEAR(A), MONTH(A), SUM(B)
group by YEAR(A), month(A)")
And it work well, but, how can I concat two values in one cell ?
I though of this:
=QUERY(Journal!A:B;"select A, SUM(B)
group by A
format A 'yyyy-MM'")
But the format operation is done AFTER the group by so it's like the group by never was.
Any idea ?
[Solution]
=query({Arrayformula(text(Foo!A:A; "yyyy-MM")) \Foo!B:B}; "select Col1, sum(Col2) group by Col1"; -1)
Because my local is "french" I've to use the '\' in the Arrrayformula and ; instead of ','...
Use the ampersand (&) to concatenate in arrayformula:
=ArrayFormula(if(len(A:A), year(A:A)&" "&month(A2:A),))
or if you don't want the space between year and month:
=ArrayFormula(if(len(A:A), year(A:A)&month(A2:A),))
EDIT:
If you want to query and sum, try:
=query({Arrayformula(text(Journal!A:A, "yyyy-MM")),Journal!B:B}, "select Col1, sum(Col2) where Col2 is not null group by Col1", 0)
or in locale that use semi-colons as argument separators:
=query({Arrayformula(text(Journal!A:A; "yyyy-MM"))\Journal!B:B}; "select Col1, sum(Col2) where Col2 is not null group by Col1"; 0)
Example spreadsheet
Related
What's the formula to find which is the most frequent character in a cell in Google Sheets?
E.G. In cell N8 it says: "What's your name?". I'd like the formula to return "a", as it is the most frequent character in N8.
you can get the total distribution like this:
=QUERY(FLATTEN(REGEXEXTRACT(A1, REPT("(.)", LEN(A1)))),
"select Col1,count(Col1) group by Col1 order by count(Col1) desc label count(Col1)''")
notice that two empty spaces are counted as well
if you want to skip them use:
=QUERY(FLATTEN(REGEXEXTRACT(A1, REPT("(.)", LEN(A1)))),
"select Col1,count(Col1) where Col1 <> ' ' group by Col1
order by count(Col1) desc label count(Col1)''")
also, keep in mind that this is case-sensitive:
to make it case-insensitive use:
=QUERY(FLATTEN(REGEXEXTRACT(LOWER(A1), REPT("(.)", LEN(A1)))),
"select Col1,count(Col1) where Col1 <> ' ' group by Col1
order by count(Col1) desc label count(Col1)''")
so to get the top value only use:
=INDEX(QUERY(FLATTEN(REGEXEXTRACT(LOWER(A1), REPT("(.)", LEN(A1)))),
"select Col1,count(Col1) where Col1 <> ' ' group by Col1
order by count(Col1) desc label count(Col1)''"), 1, 1)
This should work:
=index(Sort(filter({LEN(substitute($A$1,mid($A$1,ROw(A:A),1),"")),mid($A$1,ROw(A:A),1)},Row(A:A)<= LEN(A1)),1,true),1,2)
I'm not sure what you'd expect for when there's a tie, but it would consistently return the character most used. If you wanted to skip spaces, you could do this...
=index(Sort(filter({LEN(substitute($A$1,mid(substitute($A$1,"
",""),ROw(A:A),1),"")),mid(substitute($A$1," ",""),ROw(A:A),1)},Row(A:A)
<= LEN(substitute(A1," ",""))),1,true),1,2)
I want to filter the value in F (F>100) and group values in F according to Values in E, find the total for the group and multiply it with value in B as per the group (ie, A,B,C etc.,) and the final totals of the multiplied values for all groups
sum(A)*20+sum(B)*30+sum(C)*15 and so on
enter image description here
See if this works
=index(query({E:F, IFERROR(F:F*VLOOKUP(E:E, A:B, 2, 0))}, "Select Col1, sum(Col3) where Col2 > 100 group by Col1 label sum(Col3)''", 0))
If Col A will always have A,B,C,D,E in that order:
=arrayformula(if(A:A<>"",{A:A,QUERY({E:F},"select sum(Col2) where Col2 >100 group by Col1 label sum(Col2) '' ",0)*B:B},))
If not:
=arrayformula(if(A:A<>"",QUERY({E:F},"select sum(Col2) where Col2 >100 group by Col1 label sum(Col2) '' ",0)*query({A:B},"select Col2 where Col1 is not null order by Col1",0),))
I'm trying to select a range of data within a named range on a google sheet but after searching I still can't figure it out how to do it.
In this case, I would like to count the amount of time a club appeared within a gameweek.
Here I can do it for all the gameweek tables I have, there is no problem.
Total
=QUERY({B:C;D:E;F:G;H:I;J:K}; "SELECT Col1, SUM(Col2) WHERE Col1 <> '' AND Col1 <> 'GK' AND Col1 <> 'DEF' AND Col1 <> 'MID' AND Col1 <> 'FW' AND Col1 <> 'EXTRA' AND Col1 <> 'Club' AND Col1 <> 'count' AND Col1 MATCHES '^.{0,5}$' GROUP BY Col1 ORDER BY SUM(Col2) DESC LABEL Col1 'Club', SUM(Col2) 'count'")
But I'd like to do the same for each of the gameweek table. So far I have this
Gameweek 1
=QUERY({(B6:B15):(C6:C15);(D6:D15):(E6:E15);(F6:F15):(G6:G15);(H6:H15):(I6:I15);(J6:J15):(K6:K15)}; "SELECT Col1, SUM(Col2) WHERE Col1 <> '' GROUP BY Col1 ORDER BY SUM(Col2) DESC LABEL Col1 'Club', SUM(Col2) 'count'")
but it is not very usable as I'd have to change each range for every next table.
So I tried to make the "Gameweek 1" table as a named range gw1_clubcount and only select its adequate columns similarly as the total so that I would just have to change that for each gameweek but obviously it is not working but that's what I would like to reach.
Gameweek 1 with named range
=QUERY(gw1_clubcount {B:C;D:E;F:G;H:I;J:K}; "SELECT Col1, SUM(Col2) WHERE Col1 <> '' GROUP BY Col1 ORDER BY SUM(Col2) DESC LABEL Col1 'Club', SUM(Col2) 'count'")
I've found the INDEX function where you can select the desired row and column of the named range.That would give something like this below but that's not how you use it.
=QUERY({INDEX(gw1_clubcount,,1):INDEX(gw1_clubcount,,2);INDEX(gw1_clubcount,,3):INDEX(gw1_clubcount,,4);INDEX(gw1_clubcount,,5):INDEX(gw1_clubcount,,6);INDEX(gw1_clubcount,,7):INDEX(gw1_clubcount,,8);INDEX(gw1_clubcount,,9):INDEX(gw1_clubcount,,10)} ; "SELECT Col1, SUM(Col2) WHERE Col1 <> '' GROUP BY Col1 ORDER BY SUM(Col2) DESC LABEL Col1 'Club', SUM(Col2) 'count'")
I'm not very experienced with sheets and a little help would be very appreciated !
Here I created a solution that requires custom function:
To write a custom function:
Create or open a spreadsheet in Google Sheets.
Select the menu item Tools > Script editor.
Delete any code in the script editor.
For this problem, simply copy and paste the code below (stack function) into your script editor.
At the top, click Save save.
To use custom function:
Click the cell where you want to use the function.
Type an equals sign (=) followed by the function name and any input value — for example, =DOUBLE(A1) — and press Enter.
The cell will momentarily display Loading..., then return the result.
Code:
function stack(arr) {
var flatArr = arr.flat();
var filtered = flatArr.filter(function (el) {return el != "";});
const newArr = [];
while(filtered.length) newArr.push(filtered.splice(0,2));
return(newArr);
}
Named Ranges:
Example usage:
GAMEWEEK1:
=QUERY(stack(FLATTEN(gw1_clubcount)), "SELECT Col1, SUM(Col2) WHERE Col1 <> '' GROUP BY Col1 ORDER BY SUM(Col2) DESC LABEL Col1 'Club', SUM(Col2) 'count'")
GAMEWEEK2:
=QUERY(stack(FLATTEN(gw2_clubcount)), "SELECT Col1, SUM(Col2) WHERE Col1 <> '' GROUP BY Col1 ORDER BY SUM(Col2) DESC LABEL Col1 'Club', SUM(Col2) 'count'")
References:
Custom Function
FLATTEN
If i have 2 columns viz., ID & Name, ID column containing duplicates, and if i want to group by ID to get unique ID's but name column should be a comma-separated list, can this be possible in Google Query?
| ID | Name |
===============
| 1001 | abc |
---------------
| 1001 | def |
---------------
| 1002 | kjg |
---------------
| 1003 | aof |
---------------
| 1003 | lmi |
---------------
| 1004 | xyz |
---------------
into
| ID | Name |
====================
| 1001 | abc, def |
--------------------
| 1002 | kjg |
--------------------
| 1003 | aof, lmi |
--------------------
| 1004 | xyz |
--------------------
try:
=ARRAYFORMULA({QUERY(QUERY({A2:B, B2:B},
"select Col1,max(Col2)
where Col1 is not null
group by Col1
pivot Col3"),
"select Col1
offset 1", 0), REGEXREPLACE(TRIM(
TRANSPOSE(QUERY(TRANSPOSE(QUERY(QUERY({A2:B&",", B2:B},
"select max(Col2)
where Col1 is not null
and Col2 <> ','
group by Col1
pivot Col3"),
"offset 1", 0)),,999^9))), ",$", )})
however, this may not work for massive datasets due to TRIM (which is needed to remove empty spaces) and REGEXREPLACE (which is needed to remove the end comma) limitations. otherwise, without it, the formula can handle anything:
=ARRAYFORMULA({QUERY(QUERY({A2:B, B2:B},
"select Col1,max(Col2)
where Col1 is not null
group by Col1
pivot Col3"),
"select Col1
offset 1", 0),
TRANSPOSE(QUERY(TRANSPOSE(QUERY(QUERY({A2:B&",", B2:B},
"select max(Col2)
where Col1 is not null
and Col2 <> ','
group by Col1
pivot Col3"),
"offset 1", 0)),,999^9))})
I looked through Query specification. I could not find a solution. So I made some formulas that do the job (because I found this task interesting).
D2 contains =unique(a2:a)
E2 contains =join(", ",transpose(filter($B$2:$B,$A$2:$A=D2)))and it's copied down.
I had to copy formulas down (far from beautiful formula)
Hope you find it helpful.
Reference
UNIQUE
JOIN
TRANSPOSE
FILTER
Here is an answer using QUERY.
=ARRAYFORMULA(REGEXREPLACE(TRIM(SPLIT(TRANSPOSE(SPLIT(
CONCATENATE(TRANSPOSE(QUERY({"♦"&A2:A&"♠", B2:B&", "},
"select max(Col2) where Col2 is not null group by Col2 pivot Col1", 0))),
"♦")), "♠")), ",$", ))
This comes directly from this question.
Player0 has answers with just amazing formulas that are able to reorganise data in a huge variety of ways.
if you could live with the end-comma present in the output you can try:
=ARRAYFORMULA({QUERY(QUERY({A2:B, B2:B},
"select Col1,max(Col3)
where Col1 is not null
and Col3 <> ','
group by Col1
pivot Col2"),
"select Col1 offset 1", 0),
TRANSPOSE(QUERY(TRANSPOSE(IFERROR(VLOOKUP(QUERY(QUERY({A2:B, B2:B},
"select Col1,max(Col3)
where Col1 is not null
and Col3 <> ','
group by Col1
pivot Col2"),
"select Col1 offset 1", 0),
QUERY(QUERY({A2:B, B2:B&","},
"select Col1,max(Col3)
where Col1 is not null
and Col3 <> ','
group by Col1
pivot Col2"),
"offset 1", 0),
SPLIT(TRANSPOSE(QUERY(TRANSPOSE(IF(QUERY(QUERY({A2:B, B2:B&","},
"select max(Col3)
where Col1 is not null
and Col3 <> ','
group by Col1
pivot Col2"),
"offset 1", 0)="",,COLUMN(B2:XXX)&",")),,999^99)), ","), 0))),,999^99))})
(tho this was never tested on an ultra-massive dataset but in theory, it should handle anything too)
In cell C1:C of my table I got 6 rows with ticket id's. I like to search different spreadsheets to search for those ticket id's and calculate the total hours spent on that ticket.
I have it working using the following formula:
=QUERY({IMPORTRANGE("SPREADSHEETID";"B3:B")\ARRAYFORMULA(TO_PURE_NUMBER(IMPORTRANGE("SPREADSHEETID";"F3:F")-IMPORTRANGE("SPREADSHEETID";"E3:E")))};"SELECT SUM(Col2) WHERE Col1 = '"&C1&"' GROUP BY Col1 LABEL SUM(Col2) ''")
In this example, C1 is where the ticket ID can be found.
Now I thought I could just wrap QUERY in a ARRAYFORMULA and use C1:C instead of just C1 but that won't work. Now I could just copy and paste the above formula in every cell but there must be a cleaner way.
ANSWER
I used the following formula to make it work, thanks to Max's answer below.
=QUERY(
{
IMPORTRANGE("SPREADSHEETID";"B3:B")\
ARRAYFORMULA(
TO_PURE_NUMBER(
IMPORTRANGE("SPREADSHEETID";"F3:F") - IMPORTRANGE("SPREADSHEETID";"E3:E")
)
)
};
"
SELECT Col1, SUM(Col2)
WHERE Col1 = '" & JOIN("' OR Col1 = '";FILTER(C:C; C:C <> "")) & "'
GROUP BY Col1
LABEL SUM(Col2) ''
")
Sample formula is:
=QUERY({A:B},"select * where Col1 = '"&JOIN("' or Col1 = '",FILTER(D2:D,D2:D<>""))&"'")
No, one cannot create an array of query strings and use arrayformula(query(...)) to run them all at once.
Alternative: instead of
SELECT SUM(Col2) WHERE Col1 = '"&C1&"' GROUP BY Col1 LABEL SUM(Col2) ''
use the query
SELECT Col1, SUM(Col2) GROUP BY Col1
elsewhere on the sheet, and then use vlookup to look up the sum for each value of Col1 that you want. vlookup can be used inside of arrayformula like this:
=arrayformula(vlookup(C1:C10, E:F, 2, 0))
looks up each of values in C1..C10 in the column E (exact match required) and returns the corresponding value in column F (2nd column of the searched range).