I have a set of data that looks like the following:
Faculty (A)
Course Name (B)
Course Description (C)
Units (D)
John Doe
Math 101
Intro to Math
2 Units
John Doe
Math 102
Intermediate Math
3 Units
Jane Doe
Physics 101
Intro to Physics
4 Units
I'm trying to create a query function that organizes the data on another sheet in the following way:
Faculty (A)
Course Name 1(B)
Course Desc 1(C)
Unit Count 1(D)
Course Name 2(E)
Course Desc 2(F)
Unit Count 2(G)
John Doe
Math 101
Intro to Math
2 Units
Math 102
Intermediate Math
3 Units
Jane Doe
Physics 101
Intro to Physics
4 Units
Above is how I picture this theoretically. Here is an actual link to as sheet that shows a little closer to what I'm working with: https://docs.google.com/spreadsheets/d/18ucJ7QQx39STKSm6EqH2yYkHd5AjZNlJxIwpQ9kGXdw/edit#gid=2020540687
Any help with this would be appreciated!
use:
=ARRAYFORMULA(IFERROR(SPLIT(FLATTEN(QUERY(TRANSPOSE(QUERY(QUERY(
{A2:A, "×"&B2:B&"×"&C2:C&"×"&D2:D, B2:B&C2:C&D2:D},
"select Col1,max(Col2) where Col1 is not null group by Col1 pivot Col3"),
"offset 1", 0)),,9^9)), "×")))
This is a challenge to get unstructured data to align correctly, but I think this may be the way to do it. It is a little complicated, but for each set of 'Course Name/Course Description/Units' it requires a QUERY. Please test it on a larger set of data. I came across issues relating to unsorted source data. For testing, I suggest you name the 'Units' the same as 'Faculty' so you can see if the 'Faculty' names line across correctly.
Relative to your 4 columns of source data (A:D), this goes in cell F1:
=query(ARRAYFORMULA({countif(A1:A,A:A),COUNTIFS($A1:$A,$A1:$A,ROW($A1:$A),"<="&ROW($A1:$A)),$A:$D}),"select Col3,Col4,Col5,Col6 where Col2=1 order by Col1 desc,Col3,Col2 label Col3 'Faculty', Col4 'Course Name 1',Col5 'Course Description 1',Col6 'Units 1'",1)
The other columns don't repeat 'Faculty' so the QUERY is slightly different. Notice where Col2=2 changes... 3 for the 3rd set, 4 for the 4th set etc.
Also note that the data needs to be sorted by 'faculty with most courses' so that subsequent rows don't collapse.
In cell J1:
=query(ARRAYFORMULA({countif(A1:A,A:A),COUNTIFS($A1:$A,$A1:$A,ROW($A1:$A),"<="&ROW($A1:$A)),$A:$D}),"select Col4,Col5,Col6 where Col2=2 order by Col1 desc,Col3,Col2 label Col4 'Course Name 2',Col5 'Course Description 2',Col6 'Units 2'",1)
In cell M1:
=query(ARRAYFORMULA({countif(A1:A,A:A),COUNTIFS($A1:$A,$A1:$A,ROW($A1:$A),"<="&ROW($A1:$A)),$A:$D}),"select Col4,Col5,Col6 where Col2=3 order by Col1 desc,Col3,Col2 label Col4 'Course Name 3',Col5 'Course Description 3',Col6 'Units 3'",1)
In cell P1:
=query(ARRAYFORMULA({countif(A1:A,A:A),COUNTIFS($A1:$A,$A1:$A,ROW($A1:$A),"<="&ROW($A1:$A)),$A:$D}),"select Col4,Col5,Col6 where Col2=4 order by Col1 desc,Col3,Col2 label Col4 'Course Name 4',Col5 'Course Description 4',Col6 'Units 4'",1)
In cell S1:
=query(ARRAYFORMULA({countif(A1:A,A:A),COUNTIFS($A1:$A,$A1:$A,ROW($A1:$A),"<="&ROW($A1:$A)),$A:$D}),"select Col4,Col5,Col6 where Col2=5 order by Col1 desc,Col3,Col2 label Col4 'Course Name 5',Col5 'Course Description 5',Col6 'Units 5'",1)
Related
I have a data set that looks something like this:
Column A
Column B
category 1
Team 1
1.category 1
Team 1
2.category 2
Team 1
category 2
Team 1
category 3
Team 1
3.category 3
Team 1
I am trying to use query function with a pivot statement to calculate the occurrence of each category for team 1 (I have several other teams in the data set, but for simplicity I just wrote out my example with team 1). Unfortunately the naming of the categories are not consistent in the original data, and I cannot change them.
So I need a way to combine the results of the sum of category 1 and 1.category1, and so on.
How could I handle rewrite this to get the type of result as listed below?
Category
Team 1
category 1
2
category 2
2
category 3
2
The formula I have now is as following:
query('sheet1!A:B,"Select A, count(B) where B='Team 1' group by A pivot B label B 'Team 1'",1)
If the category names all have a similar format to those in your example (with extraneous data only at the beginning, followed by 'category N', and you don't care if zero counts per category are left blank then a more compact approach then the previous answer is (for any number of teams/categories):
=arrayformula(query({regexextract(A2:A,"category.+"),B2:B},"select Col1,count(Col1) where Col2 is not null group by Col1 pivot Col2 label Col1 'Category'",0))
formula:
=ArrayFormula(
LAMBDA(DATA,CATEGORY,
LAMBDA(RESULT,
LAMBDA(RESULT,
IF(RESULT="",0,RESULT)
)(QUERY(SPLIT(TRANSPOSE(SPLIT(RESULT,"&")),"|"),"SELECT Col1,SUM(Col3) GROUP BY Col1 PIVOT Col2 LABEL Col1'Category'",0))
)(
JOIN("&",
BYROW(CATEGORY,LAMBDA(CAT,
JOIN("&",CAT&"|"&BYROW(TRANSPOSE(QUERY(DATA,"SELECT COUNT(Col1) WHERE lower(Col1) CONTAINS'"&CAT&"' PIVOT Col2",0)),LAMBDA(ROW,JOIN("|",ROW))))
))
)
)
)({ASC($A$2:$B$7)},{"category 1";"category 2";"category 3"})
)
use ASC() to format all numbers-like values into number,
use {} to create the match conditions,
iterate the conditions with BYROW() and...
use QUERY() with CONTAINS to COUNT matches of the given conditions,
use TRANSPOSE() to turn the match results of each row sideway,
change the results into string with JOIN(), this helps to modify the row and column arrangment,
SPLIT() the data to create the correct array format we can use,
use QUERY() to PIVOT the SUM of the COUNT result as our final output.
Another approch works in a slightly different concept:
=ArrayFormula(
LAMBDA(DATA,CAT,
LAMBDA(DATA,
LAMBDA(COLA,COLB,
LAMBDA(COLA,
LAMBDA(RESULT,
IF(RESULT="",0,RESULT)
)(TRANSPOSE(QUERY({COLA,COLB},"SELECT Col2,COUNT(Col2) GROUP BY Col2 PIVOT Col1 LABEL Col2'Category'",0)))
)(REGEXEXTRACT(COLA,JOIN("|",CAT)))
)(INDEX(DATA,,1),INDEX(DATA,,2))
)(ASC(DATA))
)($A$2:$B$7,{"category 1","category 2","category 3"})
)
We can modify the Category column of the input data with REGEXEXTRACT() before sending it into query, which in this case, do make the formula looks a bit cleaner.
Inspired by #The God of Biscuits 's answer, we can now get rid of the CAT variable, which makes the formula more elastic to fit into your condition.
This REGEXEXTRACT() will extract Category value from the 1st 'category' match found to the end of the 1st 'number' after it, with any spacing in between the two value.
=ArrayFormula(
LAMBDA(DATA,
LAMBDA(COLA,COLB,
LAMBDA(RESULT,
IF(RESULT="",0,RESULT)
)(TRANSPOSE(QUERY({COLA,COLB},"SELECT Col2,COUNT(Col2) WHERE Col2 IS NOT NULL GROUP BY Col2 PIVOT Col1 LABEL Col2'Category'",0)))
)(REGEXEXTRACT(LOWER(INDEX(DATA,,1)),"((?:category)(?: +?)(?:[0-9]|[0-9])+)"),INDEX(DATA,,2))
)($A$2:$B)
)
You can also use filter with a count a like this:
=counta(filter(Sheet1!A:A,(Sheet1!A:A="category 1")+(Sheet1!A:A="1.category 1"),Sheet1!B:B="Team 1"))
Looking for recomendations for fomulas:
I have a spreadsheet filled with multiple items. I want to get the unique item and the corresponding price. I then want to compare the change in price for the inventory over a certain time. For example:
Current List
Date Product Price
1/1/2022 Fish $1.00
1/1/2022 Water $2.50
1/1/2022 Meat $3.00
31/1/2022 Water $2.00
31/1/2022 Fish $1.50
Desired outcome:
Product Total price Change in Price
Fish $2.50 $.50
Water $4.50 -$.50
Meat $3.00 None
I am still a beginner, any recomendations would be great! Thanks!
use:
=QUERY(QUERY(B2:C;
"select B,sum(C),max(C)-min(C)
where C is not null
group by B");
"offset 1"; )
Something like this for a signed change - looking for something shorter though:
=ArrayFormula({"Product","Total","Change";query(B2:C,"Select B,sum(C) where B is not null group by B label B '',sum(C) ''"),
vlookup(query({row(B2:B),B2:B},"Select max(Col1) where Col2 is not null group by Col2 label max(Col1) ''"),{row(B2:B),C2:C},2,false)
-vlookup(query({row(B2:B),B2:B},"Select min(Col1) where Col2 is not null group by Col2 label min(Col1) ''"),{row(B2:B),C2:C},2,false)}
)
I am trying to use a Google Sheet to monitor the loan of inventory IN and OUT. There are several item numbers involved. There are two named ranges: ITEMIN and ITEMOUT. I tried using this formula:
=IF(ISBLANK(ITEMOUT),"--N/A--", IF(COUNTIF(ITEMIN, ITEMOUT)=0,"IN", "OUT"))
but it only registers correctly for the first cycle. Subsequent loan outs will be registered as IN. I have then tried this formula:
=IF(ISBLANK(ITEMOUT),"--N/A--", IF(ISODD(COUNTIF(ITEMIN,ITEMOUT)), "IN", "OUT"))
I tried to capture the ODD and EVEN occurrences of the item numbers to register the OUT and IN. For example: 1 occurrence (odd) of item no. 168 = OUT, 2 occurrences (even) of item no. 168 = IN and so on. The latter formula registered the OUT and IN in the following order for a particular item number: OUT->IN->IN->OUT->OUT->IN->IN instead of OUT->IN->OUT->IN
Really hope someone can help me with this as I am not really proficient in formulas or scripts.
Thank you in advance.
Actual worksheet:
Desired worksheet:
*NOTE: Attention to the item number 160 for both images.
based on your sheet this is the IN/OUT:
=ARRAYFORMULA({QUERY(SPLIT(FLATTEN({
IF('CHECK OUT'!C2:H="",,'CHECK OUT'!A2:A&"×"&'CHECK OUT'!B2:B&"♦"&'CHECK OUT'!C2:H);
IF('CHECK IN'!C2:H="" ,,'CHECK IN'!A2:A &"×"&'CHECK IN'!B2:B &"♦"&'CHECK IN'!C2:H)}), "×"),
"select Col2 where Col2 is not null order by Col1"), IF(ISODD(COUNTIFS(QUERY(SPLIT(FLATTEN({
IF('CHECK OUT'!C2:H="",,'CHECK OUT'!A2:A&"×"&'CHECK OUT'!B2:B&"♦"&'CHECK OUT'!C2:H);
IF('CHECK IN'!C2:H="" ,,'CHECK IN'!A2:A &"×"&'CHECK IN'!B2:B &"♦"&'CHECK IN'!C2:H)}), "×"),
"select Col2 where Col2 is not null order by Col1"), QUERY(SPLIT(FLATTEN({
IF('CHECK OUT'!C2:H="",,'CHECK OUT'!A2:A&"×"&'CHECK OUT'!B2:B&"♦"&'CHECK OUT'!C2:H);
IF('CHECK IN'!C2:H="" ,,'CHECK IN'!A2:A &"×"&'CHECK IN'!B2:B &"♦"&'CHECK IN'!C2:H)}), "×"),
"select Col2 where Col2 is not null order by Col1"),
SEQUENCE(COUNTIF({'CHECK OUT'!C2:H; 'CHECK IN'!C2:H}, "<>")), "<="&
SEQUENCE(COUNTIF({'CHECK OUT'!C2:H; 'CHECK IN'!C2:H}, "<>")))), "IN", "OUT")})
So I am using a query function to count the number of instances a particular name appears in column A of another sheet, and display that result in Column B of this sheet with the respective name in Column A. Here is the function:
=ArrayFormula(QUERY(Attendance!A:A&{"",""},"select Col1, count(Col2) where Col1 != '' group by Col1 label count(Col2) 'Count'",1))
The problem is, while it works for the most part, some of the names appear twice, for instance Fred Jones appears as:
Col A | Col B
Fred Jones | 5
Fred Jones | 2
I have looked at the names, and there is no discernible difference between them, I do not understand why it is not grouping. Is there a way I can use wildcard or something to get Google to combine the names if they are nearly identical? Any help would be appreciated, thanks as always.
try:
=ARRAYFORMULA(QUERY(TRIM({Attendance!A:A}),
"select Col1,count(Col1)
where Col1 is not null
group by Col1
label count(Col1)'Count'", 1))
I'm wondering if there is a decent way to do this (without scripts) - if not, I can attempt creating a script for it but some users of this sheet will be using Excel on their computers so I'm trying to keep it scriptless as much as possible.
I have a sheet set up to display text based on certain conditions that is meant to be copied and pasted into an external program.
There is a column for months jan-dec and a column next to that where the user can input a number from 1-10 (and those numbers are associated with strings that are found with Vlookup on another sheet. They're basically "error codes" just to keep the sheet clean. But I'm just omitting this part because it's not needed for this question)
Right now, the text that populates shows:
Jan: 1
Feb: 2
Apr: 1
How could I group these by the value instead of listing them separately? Something like:
1: Jan, Apr
2: Feb
Is it possible to grab the items from that months list and put them in their own lists?
This is the current formula for reference:
=if(countif(Calculator!B2:B13,">0"),CONCATENATE(C2:C13),"None")
(Calculator sheet)B2:B13 --> column with the numbers
(Data sheet)C2:C13 --> a concatenated string that contains the month name from one cell and the number (or technically the string associated with that number as I mentioned before)
Each cell in the C column has the Jan: 1, Feb: 2 data and any month without data is left blank. When I concatenate the C cells together, it automatically omits the blank cells which is helpful but now I'd really like to group them by that value instead.
Here is the example sheet that reflects this
delete A15 and paste this in A14:
={""; ARRAYFORMULA(TEXTJOIN(CHAR(10), 1, REGEXREPLACE(TRIM(
TRANSPOSE(QUERY(QUERY({A2:A13&",", B2:B13&":"},
"select max(Col1)
where not Col2 matches ':'
group by Col1
pivot Col2"),,9^9))), ",$", )))}
UPDATE:
if order matters...
={""; ARRAYFORMULA(TEXTJOIN(CHAR(10), 1, REGEXREPLACE(TRIM(
TRANSPOSE(QUERY(QUERY({"♦"&ROW(A2:A13)&"♦"&A2:A13&",", B2:B13&":"},
"select max(Col1)
where not Col2 matches ':'
group by Col1
pivot Col2"),,9^9))), "♦\d+♦|,$", )))}
UPDATE:
={""; ARRAYFORMULA(JOIN(CHAR(10), SUBSTITUTE(REGEXREPLACE(TRIM(QUERY(QUERY({
SORT(FILTER({SUBSTITUTE(A1:A12, "'", "/"&20)*1, B1:B12&":"}, B1:B12<>""), 2, 1, 1, 1)},
"select max(Col1)
group by Col1
pivot Col2
format max(Col1) 'Mmm♦yy,'"),,99^99)), ",$", ), "♦", CHAR(39))))}