Query and give a count per group - google-sheets

I am looking for help with creating a QUERY to give a total number of times a class is listed. Thank you so much for any help. My head hurts from banging it against a wall trying to solve this.
Spreadsheet has a column for:
Clan Name ( 1 of the 3 clan names are in the column cell per row. clanA, clanB, clanC)
Class (1 class per cell per row. choice of classA, classB, classC, classD, classE, classF)
Trying to craft a query that will give a result like this:
Clan Name
Class
Total per Class
clanA
classA
#
classB
#
clanB
classA
#

Use the group by clause, like this:
=query(Data!A1:B, "select A, B, count(B) where B is not null group by A, B", 1)
The formula will repeat the clan name on every row. To only show the first instance, use a conditional formatting custom formula rule in result column A2:A, like this:
=A1
The format in the rule should set the text color to white.

Related

Google Sheets QUERY of discontinuous columns in order to import desired range

I have two google sheets in the same workbook and I am trying to import certain columns from one into the other sheet based on what hour of class was chosen. For example, I have the Date in column A, Name in B, Email in C, and Number in D and other stuff, then the Class in I.
Column A - Date
Column B - Name
Column C - Email
Column D - Number
...
Column I - Class
My goal is to import column B through D if column I has a certain class. I tried a using this if statemnt: =if('Confirmação'!I2 = A1,(=importrange("sheet_url","Confirmação!B2:D2")), "NOPE")
where A1 has the name of the class to look for, but it resulted in a #Error.
Then I tried a variety of query such as the following:
=QUERY({'Confirmação'!B2:D2,'Confirmação'!I2},"Where I = 'Terça 19h English 1'")
=QUERY({'Confirmação'!B2:D2, 'Confirmação'!I2},"Where 'Confirmação'!I = 'Terça 19h English 1'")
and also added the IfError: =iferror(QUERY('Confirmação'!B4:I4,"Where I = 'Terça 19h English 1'"),"Vaga")
Could someone correct my functions or help with a google script? Thank you! Very much appreciated! (Sorry about the Portugues-it's a project I am working on in Brazil)
In case you still want to do it using QUERY:
Using your formula with slight modification:
=QUERY({'Confirmação'!B2:D2,'Confirmação'!I2},"select * where Col3 = 'Terça 19h English 1'").
In case you want the formula to take the class name dynamically, then you can modify the formula to =QUERY({'Confirmação'!B2:D2,'Confirmação'!I2},"select * where Col3 = '"&A1&"'") where A1 is the cell with the class name.
Instead of using a QUERY, you can use the =FILTER() function to solve your problem. Doing the following:
=FILTER('OriginSheet'!B:D;'OriginSheet'!I:I = 'Certain Class')
Then you can still add more conditions:
=FILTER('OriginSheet'!B:D;'OriginSheet'!I:I = 'Class 1';'OriginSheet'!I:I = 'Class 2';'OriginSheet'!I:I = 'Class 3')
Try that and let me know if it worked.

Lookup in subtables

I want to lookup a table consisting of classes and corresponding number of students:
Given a number and a letter (e.g: 7, 'C'), I need a formula that determine # of students in the class given by them (e.g: class 7C)? A formula like:
=vlookup(A1, studentTableOf(B1), 2, 0)
Where A1 is a cell containing the character C and B1 contains the number 7 for example, and studentTableOf() is the function I am trying to figure out.
What I tried
I tried restructuring my tables (at the cost of readability) which I think made the question more simple: applying vlookup twice in a multiple-keys table. But since it affect readability, I did not like setting up my tables like this.
I would recommend using the table approach that you mentioned trying. I feel that is far more elegant and efficient.
However if that is not possible then here is my solution given the data you've shared.
Use the formula in K2 to get the # of students for the Grade mentioned in I2 and the Class mentioned in J2
=QUERY(ArrayFormula(SPLIT({(A1&"✦"&A2:A&"✦"&B2:B);(C1&"✦"&C2:C&"✦"&D2:D);(E1&"✦"&E2:E&"✦"&F2:F)}, "✦")), "select Col3 where Col1 = '"&CONCATENATE("Grade ", I2)&"' and Col2 = '"&J2&"' and Col3 is not null", 0)
How it works:
Make a table (similar to the one you mentioned trying) by adding Grade names mentioned in Row 1 against the Class name and the # of students for every grade. The part of the formula that does this is:
ArrayFormula(SPLIT({(A1&"✦"&A2:A&"✦"&B2:B);(C1&"✦"&C2:C&"✦"&D2:D);(E1&"✦"&E2:E&"✦"&F2:F)}, "✦")). If you add more Grades then you will have to update this part of the formula accordingly. Note the table made here is not elegant as it repeats values like 'Class' and '# of students' but it will not matter as move to step 2.
Use Query to ingest the table created in step 1 and then filter the results of # of students for the Grade mentioned in I2 and the 'Class' mentioned in J2.
try:
=ARRAYFORMULA(IFNA(VLOOKUP(I3; INDIRECT(
ADDRESS(3; MATCH(I2&""; REGEXEXTRACT(1:1; "\d+"); ))&":"&
ADDRESS(ROWS(A:A); MATCH(I2&""; REGEXEXTRACT(1:1; "\d+"); )+1)); 2; )))
or shorter:
=INDEX(IFNA(VLOOKUP(I3; INDIRECT(
ADDRESS(3; MATCH(H2&" "&I2; 1:1; ))&":"&
ADDRESS(ROWS(A:A); MATCH(H2&" "&I2; 1:1; )+1)); 2; )))
or different approach:
=INDEX(IFNA(VLOOKUP("Grade "&I2&I3,
{FLATTEN(FILTER(A1:F1&A3:F100, MOD(COLUMN(A:F)-1, 2)=0)),
FLATTEN(FILTER(A1:F1&A3:F100, MOD(COLUMN(A:F), 2)=0))}, 2, )))

IF cell contains, THEN return certain value with more values and return possibilities

I have a sheet with the following columns:
Column 1: contains text of the form "TS001", "TS002", "DR001", "MS002" etc.
The 2 letter in the beginning are a code for the manufacturer name, so for example "MS=Microsoft".
For the second column, I would like to have a formula that goes through the first column and searches for those letters, in order to then return the complete name of the manufacturer.
For example, it should look something like this:
Column 1
Column 2
MS001
Microsoft
TS002
Tesco
DR001
DR. Pepper
TS003
Tesco
Is something like that possible?
Thank you very much!
When you say "MS=Microsoft" it implies somewhere you have a table with that reference. For the purposes of the following example I created a sheet named ReferenceTable where column A contains the two letter code, and column B contains the name of the company. So it looks like this:
A
B
MS
Microsoft
TS
Tesco
And now in the main sheet in column B you would write the following formula:
=ARRAYFORMULA(VLOOKUP(MID(A1:A,1,2),ReferenceTable!A1:B,2,FALSE))
This will give you the name of the company, looked up from the reference table.
The array formula is there so that you only have to put this formula in cell B1, and assumes you will use the ReferenceTable sheet as a list; that way as you add records to Column A Column B is populated by the arrayformula in B1.
I'd simply use a Reference Table and a VLOOKUP formula
If cell B7 contains "MS0001"
the following formula will attempt to match just the first two letters again a reference table located in cells O7:P9
=VLOOKUP(MID(B7,1,2),O7:P9,2,FALSE)
and will return "Microsoft" when it finds "MS"
In order to achieve what you want, somewhere you need to have a list of the two letter codes and the corresponding company name.
As with all vba, there’s any number of ways to do this, but I would probably put the two letter code and company data into an array, then iterate through col1 to create the desired output for col2.
E.g below assumes the two letter code and company names are in col3 and col4 respectively, but you can change it to wherever they’re located.
Sub CompName()
Dim Cmpname () as string
Dim col1 as range, rng as range
Cmpname = range(range(“C1”), range(“D1048576”).end(xlup))
Set col1 = range(range(“A1”), range(“A1048576”).end(xlup))
For each rng in col1
For i = lbound(Cmpname, 1) to ubound(Cmpname, 1)
If left(rng, 2) = Cmpname(i, lbound(Cmpname, 2)) then
rng.offset(0,1) = Cmpname(i, ubound(Cmpname, 2))
Exit For
End if
Next
Next
End Sub
I’ve admittedly just written this on my phone and have not tested it, but hopefully there’s minimal mistakes.
I just reread your question and realized that you may actually want a formula rather than vba code.
If this is correct, using an INDEX MATCH is probably your best bet.
In this example I’ll assume the same setup as described above - col3 has company codes and col4 has company name - and this formula can be inserted into cell B1:
=index(D:D,match(left(A1,2),C:C,0))
You can then just filldown for the rest of the entries in col2.
Again, done from memory without testing so hopefully got it right.

Filter on reduced values from a column?

I'm sorry this is titled so horribly.
I have a category column in a sheet (col H) and in another sheet I've got the unique values in those columns with unique(sheetname!H)
How do I get only the categories (col H values) whose value in, say, col F, is 'credit'?
A given category will always have a given col-F value: will always be credit or debit. And will always belong to a certain person, as well. Say the person's name is in column B. How do I display the person who "belongs" to that category?
Using queries should make this simple.
Something like this should work:
=QUERY(A:H, "select H where F='credit'",0)
More details on how the information is stored would help.
The first parameter is the range of cells to perform the query on. The second parameter is the query. The third is the number of header rows at the top of data.
More info on QUERY: https://support.google.com/docs/answer/3093343?hl=en
To display the names in column B along with the categories, you can use:
=QUERY(A:H, "select B,H where F='credit'",0)
try:
={H1; FILTER(H2:H; F2:F="credit")}
for unique:
={H1; UNIQUE(FILTER(H2:H; F2:F="credit"))}

How to count # lates per student name?

sample attendance (google) sheet
I want count the number of total lates per student name on this sample sheet, e.g, how many lates Mary Love has (actual sheet has over 30,000 rows, 10 columns). If possible, this count needs to change as students have additional lates. I'd really appreciate any help someone might be able to provide. I thank you very much in advance.
In addition to previous post, a QUERY() function also seems a good option as it can output a 2D-array, containing the names and the counts in one formula (no need to drag down). As an example, try:
=query(A:G, "select A, count(B) where B ='Late' group by A ", 1)
If you want to limit the result tho those who had more then 3 late's, you can do:
=query(query(A:G, "select A, count(B) where B ='Late' group by A ", 1), "where Col2 > 3")
Also further filtering with date can be done very easily. However I think that may require some 'cleaning up' of the current data: I noticed a lot of different date formats in col D... :-)
For counting each of several students and to allow greater versatility I suggest a pivot table with Student Name for Rows, Late for Values with Summarise by: COUNTA and Late for Filter with Show: Late.
You can use the COUNTIFS function to get what you are looking for. This formula will count all matches for multiple criteria ranges and criteria (e.g. student name & late).
This is the syntax for the formula:
COUNTIFS(criteria_range1, criteria1, [criteria_range2, criteria2]…)
If you put Mary Love in cell I2, you could then put this in J2.
=countifs(B:B,"=late", A:A,I2)
Then as more rows are added it will automatically update the "lates". I would also suggest using named ranges, then you could replace B:B and A:A with the named range.
I would suggest using the =query function as documented below. If that doesn't meet your needs you could modify the above:
=if (countifs(B:B,"=Late", A:A,I2, D:D, ">="&N2) >= 3, "True", "False")
This will put "True" in the column if there are 3 or more lates, false if not. This will require you put the date you want to check against in column N2. Change N2 above if you want to use a different column.

Resources