Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have 4 columns one has id and other columns (A,B,C) has binary values.
I want the results like, columns(A,B,C) which has value = 1.Then particular Column name must be displayed in new column(D) with comma separated values.
I want the results like below. Can anyone please help me?
Id A B C D
1 1 1 0 A,B
2 0 1 0 B
3 0 1 0 B
4 1 0 1 A,C
5 1 0 1 A,C
A simple CASE expression will do it:
SELECT *,
D =
STUFF((
CASE
WHEN A = 1 THEN ',A'
ELSE ''
END +
CASE
WHEN B = 1 THEN ',B'
ELSE ''
END +
CASE
WHEN C = 1 THEN ',C'
ELSE ''
END
), 1, 1, '')
FROM tbl
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 11 months ago.
Improve this question
I expected that this query will not output 0 values, but it does. I thought that and (...) > 0 will not output 0 values. So how I can prevent the output of 0 values?
select lot.*, sum(movement.quantity) as value
from lot
left join lot_movement as movement on lot.id = movement.lot_id
where lot.item_id = 8 and movement.storage_id = 3
and (select sum(lot_movement.quantity)
from lot_movement
where lot_movement.lot_id = lot.id
) > 0
group by lot.id;
I tried to add and sum(lot_movement.quantity) \> 0, but this gives error invalid use of group function.
lots in database
lot_movements in database
output with 0 values
I see that
and (select sum(lot_movement.quantity)
from lot_movement
where lot_movement.lot_id = lot.id
group by lot_movement.lot_id) > 0
is redundant. It doesn't affect the result.
Your query doesn't give the expected result because you're filtering by lot.item_id = 8 and movement.storage_id = 3 in the where clause, but you're not applying that same filtering in the subselect.
I'm not exactly sure what you're trying to achieve, but I suspect adding a having clause instead of the subselect solves your problem:
select lot.id, sum(movement.quantity) as value
from lot
left join lot_movement as movement on lot.id = movement.lot_id
where lot.item_id = 8 and movement.storage_id = 3
group by lot.id
having sum(movement.quantity) > 0
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have a Table with Column Headings:
ID Student_Name
Roll_Number
Subject1MarksObtained
Subject1TotalMarks
Subject2MarksObtained
Subject2TotalMarks
Subject3MarksObtained
Subject3TotalMarks
Subject4MarksObtained
Subject4TotalMarks
I want to write a query to output the results for individual student who have pass at least three of the subjects.
Without seeing the data, lets make some assumptions:
A pass is awarded for a subject if the marks obtained for that subject are equal to or more than 50% of the total marks available for that subject.
The name of the table is called Enrollment
To return a list of students who have passed at least 3 subjects we can use a query similar to the following:
This solution uses CASE to evaluate a 1 for a pass and a 0 for fail for each subject, then we sum those results and only return rows that have a score of 3 or more.
SELECT ID, Student_Name, Roll_Number
FROM Enrollment
WHERE
( CASE WHEN (Subject1MarksObtained / Subject1TotalMarks) >= 0.5 THEN 1 ELSE 0 END
+ CASE WHEN (Subject2MarksObtained / Subject2TotalMarks) >= 0.5 THEN 1 ELSE 0 END
+ CASE WHEN (Subject3MarksObtained / Subject3TotalMarks) >= 0.5 THEN 1 ELSE 0 END
+ CASE WHEN (Subject4MarksObtained / Subject4TotalMarks) >= 0.5 THEN 1 ELSE 0 END
) >= 3
There are different way to approach this, but this query is simple to read and gets the job done.
If you are querying an access table, then CASE WHEN is not supported but you can use IIF or SWITCH to achieve the same results:
SELECT ID, Student_Name, Roll_Number
FROM Enrollment
WHERE
( IIF( (Subject1MarksObtained / Subject1TotalMarks) >= 0.5, 1, 0)
+ IIF( (Subject2MarksObtained / Subject2TotalMarks) >= 0.5, 1, 0)
+ IIF( (Subject3MarksObtained / Subject3TotalMarks) >= 0.5, 1, 0)
+ IIF( (Subject4MarksObtained / Subject4TotalMarks) >= 0.5, 1, 0)
) >= 3
Let's instead start by fixing your broken schema. A normalised design might look somewhat as follows:
Student
ID
Student_Name
Roll_Number
Results
StudentID
Subject
Mark
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have a basketball dataset with column A representing different teams. Is there a good way to extract the last few rows in that dataset where column A matched "The Warriors" for instance?
What I mean here is I want to find the last 3 rows before the current one where column A said "The Warriors" for example. How would I do this in R (or SQL or Matlab)?
I can propose a solution in Matlab.
Let me create at first a random table with a single column A just for the sake of demo:
T =
A
______________
'The Warriors'
'43'
'38'
'40'
'49'
'71'
'69'
'64'
'67'
'The Warriors'
'The Warriors'
'The Warriors'
'131'
'The Warriors'
'119'
'124'
'93'
'109'
'77'
'The Warriors'
'83'
'117'
'75'
'122'
'80'
'Smith'
'Johnson'
'Williams'
'Jones'
'Brown'
Now it's possible to create a boolean vector which contains true (1) in position i if the i-th row contains the string 'The Warriors':
matchresult=cellfun(#(x) strcmp(x,'The Warriors'),T.A);
Indeed now matchresult has the form:
matchresult =
1
0
0
0
0
0
0
0
0
1
1
1
0
1
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
And now we can scan this vector instead of the whole table to find the last 3 rows:
for i=4:length(matchresult) % since we want 3 rows we can start scanning from the 4th
if(sum(matchresult(1:i-1))>=3) % if there are at least 3 ones in previous rows
fprintf('Scanning row #%d:\n',i); % see the row index we're scanning
find(matchresult((1:i-1)),3,'last') % find 1s in previous rows and display last 3 indices
end
end
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
How can I list the data with id x first and then followed by numerical order?
For instance, I have data like this:
0,
1,
1,
0,
1,
2,
56,
4
and I want the following result:
1,
1,
1,
0,
0,
2,
4,
56
In addition, I want the order for items with id 1 to be a column x, while the order for items with id not 1 to be a column y.
You can do this with conditionals in the order by clause. Here is a simple way in MySQL:
order by (id = 1) desc, id;
The expression id = 1 evaluates to 1 when the id takes on the specified value. It evaluates to 0 otherwise.
The order by is saying to order by this expression first, and then by the id.
EDIT:
If you want to order everything else by another column and the columns are of the same type:
order by (id = 1) desc,
(case when id = 1 then x else y end)
Otherwise, you can split it:
order by (id = 1) desc,
(case when id = 1 then x end),
(case when id = 1 then NULL else y end)
What's the best way to compare two queries by two columns? these are my tables:
This table shows exam questions
idEvaluation | Question | AllowMChoice | CorrectAnswer|
1 1 0 3
1 2 1 4
1 2 1 5
1 3 0 9
This table shows a completed exam
idExam| idEvaluation | Question | ChosenAnswer|
25 1 1 2
25 1 2 4
25 1 2 5
25 1 3 8
I have to calculate the percentage of correct Answers, considering to certain questions may allow multiple selection.
Correct Answers / Total Answers * 100
thanks for your tips!
This code will show you a listing of Questions and whether or not they were answered correctly.
select
A.Question,
min(1) as QuestionsCount,
-- if this evaluates to null, they got A) the answer wrong or B) this portion of the answer wrong
-- we use MIN() here because we want to mark multi-answer questions as wrong if any part of the answer is wrong.
min(case when Q.idEvaluation IS NULL then 0 else 1 end) as QuestionsCorrect
from
ExamAnswers as A
left join ExamQuestions as Q on Q.Question = A.Question and Q.CorrectAnswer = A.ChosenAnswer
group by
A.Question -- We group by question to merge multi-answer-questions into 1
Output Confirmed:
Note, the columns are intentionally named this way, as they are to be included as a subquery in part-2 below.
This code will give you the test score.
select
sum(I.QuestionsCorrect) as AnswersCorrect,
sum(I.QuestionsCount) as QuestionTotal,
convert(float,sum(I.QuestionsCorrect)) / sum(I.QuestionsCount) as PercentCorrect -- Note, not sure of the cast-to-float syntax for MySQL
from
(select
A.Eval,
A.Question,
min(1) as QuestionsCount,
min(case when Q.idEvaluation IS NULL then 0 else 1 end) as QuestionsCorrect
from
ExamAnswers as A
left join ExamQuestions as Q on Q.Question = A.Question and Q.CorrectAnswer = A.ChosenAnswer
where
A.Eval = 25
group by
A.Question, A.Eval) as I
group by
I.Eval
Output Confirmed:
This will communicate the general concept. Your column names idEvaluation and Eval are difficult for me to understand, but I'm sure you can adjust the code above to suit your purposes.
Note, I did this in sql server, but I used fairly basic SQL functionality, so it should translate to MySQL well.