how to create a sql query for my given criteria? - mysql

I have one table named task_assignment.It has following 6 fields named as:
testId,quesId,evaluatorId,studId and marks
Actually this table is used to store marks for each test including each evaluators marks for each students by question id wise.
I have testId=1, quesId=Q1 and studId=S1 as a input. So, i want to get the following information in the select query.ie,Both evaluators(E1,E2) marks for the given input.
The sql query don't written more than one row for this...I want query output is :20,15 in a single row.
Please guide me to get out of this issue...

I think you won't be able to get your desired output 20, 15, since there is only one record which satisfies your criteria testId = 1, quesId = Q1, studId = S1.
But to answer your question, here's my query:
SELECT GROUP_CONCAT(marks)
FROM task_assignment
WHERE testId = 1
AND quesId = 'Q1'
AND studId = 'S1';
I've tried it in SQL Fiddle.
EDIT 1
If you want to parse the output of the query in your C# code to store them in separate variables, you can use the Split function:
string marks = "20, 15"; //Suppose that this value came from database
int mark1 = Convert.ToInt32(marks.Split(',')[0]);
int mark2 = Convert.ToInt32(marks.Split(',')[1]);
The code is still error-prone depending on the value of the marks variable, just make sure you have validated the value.
This might be unrelated to the question, but still to help you on your task, that's my answer.

Related

Filter students that have not passed a subject yet

I have a MySql table and it has following values:
table name 'results'
Reg.No SubjectCode Attempt Pass/Fail
112108 CMIS 1113 1 fail
112110 CMIS 1114 1 pass
112119 CMIS 1114 1 fail
112108 CMIS 1113 2 fail
112107 CMIS 1113 1 fail
112108 CMIS 1113 3 pass
Students can have several attempts to pass the subject.
Student should pass each subjects to get the degree.
Some student pass in first attempt.
Some take more than 3 attempt.
However student can try until he/she pass.
But some still remain fail.
So I want to get the Reg.No of students who are still unable to pass the subject.
Eg.: 112119 and 112107 are still unable to pass their subject.
I was unable to write a query for this problem.
I would suggest using aggregation:
SELECT `Reg.No`, SubjectCode, SUM(`Pass/Fail` = 'Pass')
FROM results
GROUP BY `Reg.No`, SubjectCode
HAVING SUM(`Pass/Fail` = 'Pass') = 0;
The HAVING clause counts the number of results for each student and course where the last column is 'Pass'. In MySQL, booleans are treated as integers in a numeric context, with true being 1. So, sum(Pass/Fail= 'Pass') counts the number of times a student passed the course. The = 0 says the student never passed the course.
As a suggestion, don't put special characters such as / and . in column names. That requires escaping the columns and just makes the code harder to write because it is filled with backticks.
You don't need a subquery for this.
SELECT `Req.No`, `SubjectCode`, max(`Pass/Fail`) AS `Pass/Fail`
FROM results
GROUP BY 1, 2
HAVING max(`Pass/Fail`) = 'fail'
Assuming Pass/Fail is a string type, so 'pass' > 'fail'.
You only get students who tried and failed, but not those who never tried (and are not in this table at all).
I really wouldn't use column name with special characters. Very error prone.
Like this?
SELECT Req.No FROM results WHERE `Pass/Fail` = 'fail';
This is pretty basic SQL. You should read some tutorials.
Edit: OK after playing around with a bit, I came to this query:
SELECT `Req.No` FROM results WHERE `Req.No` NOT IN(SELECT `Req.No` FROM results WHERE `Pass/Fail` = 'pass');
http://sqlfiddle.com/#!2/b2bd80/17

Using Django Count() with conditional lookup types

So I'm trying to aggregate exam data, and because the database lives on another server I'm trying to reduce this to as few database calls as possible.
I have this model (whose corresponding table is in a mySQL database if that matters):
class Exam(models.Model):
submitted = models.BooleanField(default=False)
score = models.DecimalField(default=Decimal(0))
And this query:
>>> exam_models.Exam.objects\
... .using("exam_datebase")\
... .aggregate(average=Avg("score"),
... total=Count("submitted"))
{'average': 22.251082, 'total': 231}
What I'm looking for is a way to also retrieve the number of passed exams, something along the lines of:
>>> exam_models.Exam.objects\
... .using("exam_datebase")\
... .aggregate(average=Avg("score"),
... total=Count("submitted"))
... passed=Count("score__gte=80"))
{'average': 22.251082, 'total': 231, 'passed': 42}
I know I can just send another query using .filter(score__gte=80).count(), but I was really hoping to get both the total count and the passing count on the same aggregate. Any ideas?
You are either going to need two queries, or do the aggregation manually.
To see why, let's consider the underlying SQL that Django generates and uses to query the database.
Exam.objects.aggregate(average=Avg("score"), total=Count("submitted"))
roughly translates to
SELECT AVG(score), COUNT(submitted)
FROM exam
The "Count" part of the aggregate is applying to the SELECT clause in the underlying sql query. But if we want to include only scores greater than some value, the SQL query would need to look something like this:
SELECT AVG(score), COUNT(submitted)
FROM exam
WHERE score > 80
Filtering Exams with a particular "score" is applies to the WHERE or HAVING clause of the underlying SQL statement.
Unfortunately, there is not really a way to combine these two things. So, you are stuck doing two queries.
Having said all that, if you REALLY want to do a single query, one option is to just do the aggregation in your python code:
exams = Exam.objects.all()
total_score = 0
total_submitted = 0
passed = 0
for exam in exams:
total_score += exam.score
if exam.submitted:
total_submitted += 1
if exam.score >= 80:
passed += 1
exam_aggregates = {
'average': total_score / len(exams),
'submitted': total_submitted,
'passed': passed,
}

mysql search with multiple conditions

Need a bit of help writing query as I have database containing 1000's records of records.
Basically I have a database that contains the following fields
entryID
date
toothNumber
procedureName
studentName
tutorName
isolationSkill
isolationKnowledge
cavitySkill
cavityKnowledge
matrixSkill
matrixKnowledge
restorativeSkill
restorativeKnowledge
I want to write a query that searches all the records for a particular name(for example "Joe Bloggs") and the procedureName contains "Class II"
On top of that I want it to return the amount of times the Values N, B and C appear in the isolationskill - restorativeKnowldge columns.
So in the end I can see a list like this
Hope this is making sense. Let me know if you require any more information.
Thanks in advance
I think something like this would give you what you want, without you posting what you would like to see, kinda hard to tell, but this will pop out all the rows just like normal, and then give you a count field for each of the given Value n, B, C fields. Apply this syntax multiple times to get the exact results you are looking for on the different fields.
SELECT
entryID,
date,
procedurename,
studentName,
tutorName,
restorativeSkill,
isolationKnowledge,
cavitySkill,
cavityKnowledge,
matrixSkill,
matrixKnowledge,
restorativeknowledge,
SUM(IF(isolationSkill = 'N', 1,0)),
SUM(IF(restorativeKnowldge = 'B', 1,0)) FROM records
WHERE procedureName = 'Class II' and Name = "Joe Bloggs";

How do I copy multiple values from within the same table to other values in that same table in SQL?

First of all I'm rather new to SQL and so even though I believe a similar question was asked in this thread ( SQL Query - Copy Values in Same Table ) I literally can't understand it well enough to utilize the information. For that I apologize.
Now, I have a table that looks something like this:
company id | parameter name | parameter title
P | Parameter One | First Parameter
P | Parameter Two | Second Parameter
P | Parameter Three| Third Parameter
W | Parameter One | NULL
W | Parameter Two | NULL
Except that my table obviously has quite a lot of rows. I already went through filling in all the parameter titles where the company id was 'P' and would like to avoid manually doing the same for those with company id 'W'. My question is what SQL statement (this is in Microsoft SQL Server 2008) can I use to copy the values in the column "parameter title" where the company id is 'P' to the values in the same column where the company id is 'W' and both parameter names match up (W has less parameters than P)?
Using the previously linked thread I was able to come up with the following, but it spits out an error and I know it's not done correctly:
UPDATE COMP_PARAMETER_COPY
SET PARAM_TITLE=(SELECT PARAM_TITLE FROM COMP_PARAMETER_COPY P
WHERE P.COMP_ID = 'P' AND P.PARAM_TITLE=PARAM_TITLE)
WHERE COMP_ID='W'
(I'm playing around with a copy of the table instead of the actual table)
The error I get is "Msg 512, Level 16, State 1, Line 1
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
The statement has been terminated."
Thank you for your help and advice,
-Asaf
You need to ensure that your subquery is only returning one result. Right now that error message is telling you that you're getting more than one record returned.
UPDATE W
SET PARAM_TITLE = (
SELECT PARAM_TITLE FROM COMP_PARAMETER_COPY P
WHERE P.COMP_ID = 'P' AND P.PARAM_NAME = W.PARAM_NAME
)
FROM COMP_PARAMETER_COPY W
WHERE W.COMP_ID = 'W'
Try giving the above SQL a whirl. This could still give you more than one result, but without knowing what your table looks like and what the data constraints are it's hard to give you something guaranteed to work.
Try adding the DISTINCT keyword to your query:
UPDATE COMP_PARAMETER_COPY
SET PARAM_TITLE=(SELECT DISTINCT PARAM_TITLE FROM COMP_PARAMETER_COPY P
WHERE P.COMP_ID = 'P' AND P.PARAM_TITLE=PARAM_TITLE)
WHERE COMP_ID='W'

Linq Group on a multi-level object with select statement

I've got 3 dataset objects that are nested with each other using entity set objects. I am selecting the data like this
var newList = from s in MainTable
from a in s.SubTable1 where a.ColumnX = "value"
from b in a.Detail where b.Name = "searchValue"
select new {
ID = s.ID,
Company = a.CompanyName,
Name = b.Name,
Date = s.DueDate
Colour = b.Colour,
Town = a.Town
};
and this works fine, but the trouble is there are many records in the Detail object-list/table for each Name value so I get a load of duplicate rows and thus I only want to display one record per b.Name. I have tried putting
group s by b.Name into g
before the select, but then this seems to stop the select enabling me to select the columns I want (there are more, in practice). How do I use the group command in this circumstance while still keeping the output rows in a "flat" format?
Appending comment as answer to close question:-
Of course that if you group your results, you cant get select a column of a child, thats because there may be more than one childs and you have to specify an aggregate column for example the sum,max etx –