Google Sheets Query WHERE clause just returns first row of data - sql

I have a sheet which I am trying to use to show an overview of students results in a number of subjects, with each student and their results in separate rows.
OVERVIEW
studentID, English, Maths, etc
1, result1, result2, etc
2, result3, result4, etc
The result data comes from another system and is in a separate sheet. Each result for each subject is a separate row where the first column is the student ID, the second is the subject and the third is the result.
RESULTSET
1, ENGLISH, result 1
1, MATHS, result 2
etc.
I've been trying various forms of a query like this
=query(RESULTSET!A1:C,"SELECT C WHERE A = '1' AND B = 'ENGLISH'",1) but the query only ever returns the first result from the first row of data in RESULTSET.
Here is a link to a test spreadsheet containing data and queries that reproduces the issue: https://docs.google.com/spreadsheets/d/15xLAyHumL2pC8mRfA4Qs9xMyrWZvK86kmoi2kBWnB34/edit?usp=sharing
I am expecting to see results from the result set that matches each student ID and subject, but I am only ever seeing the first result irrespective of ID or subject.

Remove the single quotes around the reference to column A and set the headers argument in query() to zero. In B2 try
=iferror(query('result set 1'!$A$1:$C58,"SELECT C WHERE A = "&$A2&" AND B = '"&UPPER(B$1)&"'",0))
Fill down to the right and down as far as needed and see if that works?
Another option would be to use in B2
=ArrayFormula(iferror(vlookup($A$2:$A$8&B$1, {'result set 1'!$A:$A&'result set 1'!$B:$B, 'result set 1'!$C:$C}, 2, 0)))
and fill to the right (make sure there is no data below row 2).

Related

How to combine rows in BigQuery that share a similar name

i'm having trouble creating a query that'll group together responses from multiple rows that share a similar name and count the specific response record in them.
the datatable i currently have looks like this
test_control
values
test
selected
control
selected
test us
not selected
control us
selected
test mom
not selected
control mom
selected
what i'd like, is an output like the below that only counts the number of "selected" responses and groups together the rows that have either "control" or "test" in the name"
test_control
values
test
3
control
1
The query i have below is wrong as it doesn't give me an output of anything. The group by section is where im lost as i'm not sure how to do this. tried to google but couldn't seem to find anything. appreciate any help in advance!!!
SELECT distinct(test_control), values FROM `total_union`
where test_control="%test%" and values="selected"
group by test_control, values
use below
SELECT
REGEXP_EXTRACT(test_control, r'^(TEST|CONTROL) ') AS test_control,
COUNTIF(values = 'selected') AS values
FROM `total_union`
GROUP BY 1
As mentioned by #Mikhail Berlyant, you can use REGEX_EXTRACT to match the expression and COUNTIF to get the count of the total number of matching expressions according to the given condition. Try below code to get the expected output :
Code
SELECT
REGEXP_EXTRACT(test_control, r'^(test|control)') AS test_control,
COUNTIF(values = "selected") AS values
FROM `project.dataset.testvalues`
group by 1
Output

SQL - Similar Update Queries Produce Varying Results

I am super new to SQL and have two queries I think should produce the same output but they don't. Can someone figure out the difference between them?
The input table for this simple example has two columns, letter and extra. The data in the first column is a random letter from the list ['a', 'b', 'c', 'd', 'e'] and extra should not matter (I think?). These are the queries:
update
tbl
set
extra = letter;
and:
update
tbl
set
extra = (select
letter
from tbl);
The resulting tables these produce are:
e|e
e|e
c|c
e|e
b|b
...
and:
e|e
e|e
c|e
e|e
b|e
...
respectively.
I expect the first output for both queries, how come the second one turns out as it does?
EDIT:
The reason I ask this question is because what I want to do is a bit more involved than this simple example and I believe I need the subquery. I am trying to add a kind of normalisation column, like this:
update
tbl
set
extra = 1 / (select
norm
from
tbl
INNER JOIN
(SELECT
letter, count(*) as norm
FROM
tbl
GROUP BY letter) as tmp
ON
tbl.letter = tmp.letter);
Alas, this obviously doesn't work because of the above.
What your first query is saying:
Set the value of extra to the value of letter in the same row.
What the second query is saying:
Pick a value from the column "letter" in the table, and update every row in the table to have the column 'extra' contain that value.
They are different instructions, so you get different results.

Retrieving Columns with count greater than 1 - Google Sheet Query

I'm using Google sheets, and I want to get the data from one sheet to another where I want only the columns with count > 1.
Let's say we have 3 columns A, B, and C. I tried the following (the first sheet name is "Form Responses 1"):
I thought about using a query in the second sheet as: =query('Form Responses 1'!A1:Z, "Select A having count (A) >1 union select B having count (B) >1 union select C having count (C) > 1"). But I got a parse error where it seems that union and having are not supported in google sheets query.
How can I achieve this (whether it's using query or any other Google sheets function that can work)?
More details:
The first sheet contains info about exercises conducted during a lecture and it gets its data from a Google Form (so the responses are fed in this sheet). Here is a screenshot of it:
Please note that the form is divided into sections. When the user selects the course, the attendance, the participation, and adds a comment, then they go to the next section, the next section will be based on the selected course, the newly opened section will have the exercise name and rating questions (the exercise name is a dropdown list with items that are prefilled and specific to the selected course). That's why, you can see that "exercise name" and "rate the exercise" columns are repeated because we have 2 sections in this form.
The second sheet should contain the data of a selected course only (either mobile dev or web dev) which can be achieved easily through a query with a where clause. But, in addition to that, it shouldn't contain the empty columns of "exercise name" and "rate the exercise" as they correspond to another section. So, it should have only one exercise name column and one rating column that correspond to the selected course. Here is a screenshot if we only use a query with where clause without removing the extra name and rating columns:
Here is a screenshot with the desired result:
Thanks.
why not use just:
=QUERY('Form Responses 1'!A1:Z, "select A,B,C,D,E,F,G where F is not null", 1)
Use "OR" condition
Eg:-
QUERY(Data!A:R,"select A, N, P where N>0 or P>0")
where A column has country and N, P columns have population values

How to count unique occurences of string in table for separate records in apex 5

I am trying to automatically count the unique occurrences of a string saved in the table. Currently I have a count of a string but only when a user selects the string and it gives every record the same count value.
For example
Below is a image of my current table:
From the image you can see that there is a Requirement column and a count column. I have got it to the point were when the user would select a requirement record (each requirement record has a link) it would insert the requirement text into a requirement item called 'P33_REQUIREMENT' so the count can have a value to compare to.
This is the SQL that I have at current:
SELECT (SELECT COUNT(*)
FROM DIA_ASSOCIATED_QMS_DOCUMENTS
WHERE REQUIREMENT = :P33_REQUIREMENT
group by REQUIREMENT
) AS COUNT,
DPD.DIA_SELECTED,
DPD.Q_NUMBER_SELECTED,
DPD.SECTION_SELECTED,
DPD.ASSIGNED_TO_PERSON,
DAQD.REFERENCE,
DAQD.REQUIREMENT,
DAQD.PROGRESS,
DAQD.ACTION_DUE_DATE,
DAQD.COMPLETION_DATE,
DAQD.DIA_REF,
DA.DIA,
DA.ORG_RISK_SCORE
FROM DIA_PROPOSED_DETAIL DPD,
DIA_ASSOCIATED_QMS_DOCUMENTS DAQD,
DIA_ASSESSMENTS DA
WHERE DPD.DIA_SELECTED = DAQD.DIA_REF
AND DPD.DIA_SELECTED = DA.DIA
This is the sql used to make the table in the image.
This issue with this is, it is giving every record the same count when the user selects a requirement value. I can kind of fix this by also adding in AND DIA_SELECTED = :P33_DIA into the where clause of the count. DIA_SELECTED being the first column in the table and :P33_DIA being the item that stores the DIA ref number relating to the record chosen.
The output of this looks like:
As you can see there is only one count. Still doesn't fix the entire issue but a bit better.
So to sum up is there a way to have the count, count the occurrences individually and insert them in the requirements that are the same. So if there are three tests like in the images there would be a '3' in the count column where requirement = 'test', and if there is one record with 'test the system' there would be a '1' in the count column.
Also for more context I wont know what the user will input into the requirement so I can't compare to pre-determined strings.
I'm new to stack overflow I am hoping I have explained enough and its not too confusing.
The following extract:
SELECT (SELECT COUNT(*)
FROM DIA_ASSOCIATED_QMS_DOCUMENTS
WHERE REQUIREMENT = :P33_REQUIREMENT group by REQUIREMENT ) AS COUNT
Could be replaced by
SELECT (SELECT COUNT(*)
FROM DIA_ASSOCIATED_QMS_DOCUMENTS
WHERE REQUIREMENT = DAQD.REQUIREMENT ) AS COUNT
Which would give you - for each line, the number of requirements that are identical.
I'm not completely certain it is what you are after, but if it isn't, it should give you some ideas on how to progress (or allow you to indicate where I failed to understand your request)

Bringing back multiple max on a single column in sql

I have a spreadsheet with customer accounts and when we get a new account it gets added on using a reference account number i.e. Anderson Electrical would be AND01 etc. I'm trying to use sql to bring back the highest number from each variation of letterings e.g. if AND01 already existed and our highest company value was AND34 then it would just bring back AND34 rather than 1 to 34.
Each account has the first 3 letters of there company name followed by whatever the next number is.
Hope I have explained this well enouh for someone to understand :)
For a single reference account:
select max(AcctNum)
from Accounts
where left(AcctNum, 3) = <reference account>
If you want it for all at once:
select left(AcctNum, 3) as ReferenceAcct, max(AcctNum)
from Accounts
group by left(AcctNum, 3)
Not sure if that's what you're asking but if you need to find max value that is part of a string you can do it with substring. So if you need to find the highest number from a column that contains those values you can do it with:
;WITH tmp AS(
SELECT 'AND01' AS Tmp
UNION ALL
SELECT 'AND34'
) SELECT MAX(SUBSTRING(tmp, 4, 2)) FROM tmp GROUP BY SUBSTRING(tmp, 0, 3)
That's a little test query that returns 34 because I'm grouping by first 3 letters, you probably want to group it by some ID.