I have a query who works correctly, but where I want to make a change.
The query counts all notes for id_service = 89.
The notes are numbers between 0 and 3 not more.
My query counts all those notes to get an Average.
All works fine.
The change what I want is, that he counts only the notes between 1 and 3 (not 0).
I don't know how I can do that.
Example:
This query count how much time I get the number 3 with all conditions.
Here the query:
SELECT round( avg( AVG =3 ) * count( AVG ) ) AS New
, sma_famille.famille
FROM (
SELECT ROUND( SUM( note ) / count( note ) ) AS AVG
, sma_famille.famille
, sma_agents.nom
FROM sma_notes
INNER JOIN sma_famille
ON sma_famille.id_service =89
INNER JOIN sma_agents
ON sma_notes.id_agent = sma_agents.id_agent
INNER JOIN sma_service_activite
ON sma_service_activite.id_activite = sma_notes.id_activite
AND sma_service_activite.id_famille = sma_famille.id_famille
AND sma_service_activite.id_service = sma_famille.id_service
GROUP BY sma_famille.famille, sma_agents.nom
) AS FN
LEFT JOIN sma_famille
ON sma_famille.id_service =89
AND FN.famille = sma_famille.famille
GROUP BY FN.famille
An example:
In Bio I can give 2 notes per persons like Bio Part1 and Bio Part2.
In my example I have two persons.
I give in Bio Part1 the note "3" for both and in Bio Part2 i don't give a note, so that there are the note "0"!
Here the result of my query:
That is what I get:
Note Math English Bio
1 0 0 0
2 0 0 2
3 0 0 0
That is what I want:
Note Math English Bio
1 0 0 0
2 0 0 0
3 0 0 2
Without the note "0" I must get an average of 100% for the note "3".
Now i get:
Note Math English Bio
1 0
2 0
3 2
And not
Note Math English Bio
1 0 0 0
2 0 0 0
3 0 0 2
How can i get the "0" in the resultset
Anybody an idea?
One way to get a count of values > 0 would be:
count(case when note > 0 then note end)
(Where note is 0, the case evaluates as null which is not counted.)
Although the simplest way might be
sum(sign(note))
Related
From this table
groupId
flag
flagValue
1
0
500
2
0
100
1
1
10
2
1
50
3
0
100
1
1
200
3
1
1000
2
1
50
I need this result
groupId
flag1
flag0
valFlag1
valFlag0
totalFlags
1
2
1
210
500
3
2
2
1
100
100
3
3
1
1
1000
100
2
where
flag1 is number of times flag is 1 for a particular group
flag0 is number of times flag is 0 for a particular group
valFlag1 is sum of flagVal when flag is 1
valFlag0 is sum of flagVal when flag is 0
totalFlags is sum of total flags associated with a group
I am stuck as to how to actually count values based on an IF condition.
Anyhelp is appreciated. Thanks.
I have used a table named group_table with your values
Try using this:
SELECT
g.`groupId`,
SUM(g.`flag`=1 ) AS flag1,
SUM(g.`flag`=0) AS flag0,
SUM(CASE WHEN g.`flag`=1 THEN g.`flagValue` ELSE 0 END) AS valFalg1,
SUM(CASE WHEN g.`flag`=0 THEN g.`flagValue` ELSE 0 END) AS valFalg0,
COUNT(*) AS totalFlags
FROM
`group_table` g
GROUP BY g.`groupId`
If you have to use the IF,
SELECT
g.`groupId`,
IF(g.`flag`=1,1,0 ) AS flag1,
IF(g.`flag`=0,1,0) AS flag0,
SUM(IF(g.`flag`=1,g.`flagValue`,0 )) AS valFalg1,
SUM(IF(g.`flag`=0,g.`flagValue`,0 )) AS valFalg0,
COUNT(*) AS totalFlags
FROM
`group_table` g
GROUP BY g.`groupId`, flag1, flag0
They'll produce the same result
I have a table like below
SUBJECT - MARKS - SEMESTER
MATH - 50 - 1
SCIENCE - 60 - 1
ENGLISH - 70 - 1
MATH - 60 - 2
SCIENCE - 80 - 2
ENGLISH - 90 - 2
I want to produce a output like below. The problem is, even there is no data between 0-10 range I want 0 in all three columns. I am unable to achieve using "group by" and "sum". Do any of you have any idea
RANGE MATH SCIENCE ENGLISH
0-10 0 0 0
10-20 0 0 0
20-30 0 0 0
30-40 0 0 0
40-50 0 0 0
50-60 1 0 0
60-70 1 1 0
70-80 0 0 1
80-90 0 1 0
90-100 0 0 1
You can do this, but you need to define the ranges, either as a reference table or in the query. The rest is conditional aggregation:
select r.range,
sum(subject = 'MATH' and t.marks is not null) as Math,
sum(subject = 'SCIENCE' and t.marks is not null) as Science,
sum(subject = 'English' and t.marks is not null) as English
from ((select 0 as mins, 9.99 as maxs, '0-10' as range) union all
(select 10 as mins, 19.99 as maxs, '10-20' as range) union all
. . .
(select 90 as mins, 100 as maxs, '90-100' as range)
) left join
table t
on t.marks between r.mins and r.maxs
group by r.range
order by min(r.mins);
By running the following query I will get the result below. I want to convert this result into rows and whatever is there as row over ther those I want to convert into columns.
I want that project_level and account_level to come in rows and the remaining in rows goes to column.
SELECT S.Description,T.Project_Level,S.Account_Level FROM
(
SELECT DISTINCT SM.Description, COUNT(VA.FK_Status_ID) AS Project_Level,SM.Seq
From DeliveryPlatform_APPS.VA.DP_VA_Item_Status_Master SM
LEFT OUTER JOIN DeliveryPlatform_APPS.VA.DP_VA_Items VA ON SM.Status_ID = VA.FK_Status_ID
AND VA.FK_DP_Entity_Type_ID = 1 AND FK_DP_Entities=671
GROUP BY SM.Description,SM.Seq,FK_Status_ID
) AS T
INNER JOIN
(
SELECT DISTINCT SM.Description, COUNT(VA.FK_Status_ID) AS Account_Level,SM.Seq
From DeliveryPlatform_APPS.VA.DP_VA_Item_Status_Master SM
LEFT OUTER JOIN DeliveryPlatform_APPS.VA.DP_VA_Items VA ON SM.Status_ID = VA.FK_Status_ID
AND VA.FK_DP_Entity_Type_ID = 1 AND FK_DP_Entities=671
GROUP BY SM.Description,SM.Seq,FK_Status_ID
) AS S
ON S.Description=T.Description
--ORDER BY Seq
Description Project_Level Account_Level
Accepted 0 0
Closed 0 0
Delivered 0 0
Dropped 0 0
Open 0 0
Parked 0 0
Shortlisted 0 0
Work In Progress 0 0
You should check SQL Server PIVOT and UNPIVOT techniques to accomplish your intent:
http://msdn.microsoft.com/en-us/library/ms177410(v=sql.105).aspx
I'm working with MySQL, and I have the following schema:
id school round score win loss tie
2 My School Name 1 10 1 0 0
3 My School Name 2 20 0 1 0
4 My School Name 3 30 1 0 0
5 My School Name 4 40 1 0 0
6 My School Name 5 50 1 0 0
7 My School Name 6 60 0 0 1
And I need the following output, grouped by school name
School Round1 Round2 Round3 Round4 Round5 Round6 wins losses ties
My School Name 10 20 30 40 50 60 4 1 1
So far I feel like I can use GROUP BY School and SUM(win) as wins to get most of the functionality out of it. The hard part, though, is to get those Round_ fields.
Does anyone know how to do this? Thanks in advance, any help would be much appreciated!
Edit: to clarify, I know I have 10 rounds exactly.
We can use a SELECT statement with a GROUP BY school to create a record for each school. The ties, wins, and losses columns are readily calculated with the SUM aggregate function, as you noted. To target a specific round, we can use some clever math (to avoid verbose conditional statements like the one CodeByMoonlight suggested):
If we want to target round R, we note that "round-R" is 0 only when round == R, otherwise it isn't 0. When we take the NOT of "round-R", 0 gets inverted to 1, while everything else gets set to 0. Now, if we multiply !(round-R) by the score of that round, it will give us 0 when the round is not R (as 0*score = 0) and it will give us "score" when the round is R (as 1*score = score). Next, when we take the SUM of this value over the columns, we add score when round=R and 0 otherwise, effectively giving us just the round R score.
Putting that all together gives:
SELECT school AS `School`,
SUM(!(round-1)*score) AS `Round1`,
SUM(!(round-2)*score) AS `Round2`,
SUM(!(round-3)*score) AS `Round3`,
SUM(!(round-4)*score) AS `Round4`,
SUM(!(round-5)*score) AS `Round5`,
SUM(!(round-6)*score) AS `Round6`,
SUM(!(round-7)*score) AS `Round7`,
SUM(!(round-8)*score) AS `Round8`,
SUM(!(round-9)*score) AS `Round9`,
SUM(!(round-10)*score) AS `Round10`,
SUM(win) AS `wins`,
SUM(loss) AS `losses`,
SUM(tie) AS `ties`
FROM `RoundScores` GROUP BY `school`
where RoundScores is the table in question.
EDIT:
If we do not want to manually add 10, we can use prepared statements :
# Store all the conditionals in a string:
# I was not able to to have round loop from 1 to 10, so I iterated over
# all distinct values of 'round' present in the table.
SET #s = "";
SELECT `round`, (#s := CONCAT( #s , "SUM(!(round-",round, ")*score) AS `Round",round, "`," )) FROM `RoundScores` GROUP BY `round`;
# Combine the conditionals from before with the rest of the statement needed.
SET #qry = CONCAT("SELECT school AS `School`,",#s,"SUM(win) AS `wins`,SUM(loss) AS `losses` FROM `RoundScores` GROUP BY `school`");
# Prepare and execute the statement.
PREPARE stmt1 FROM #qry;
EXECUTE stmt1;
TRY WITH UNION ( not tested)
SELECT SUM(win) AS wins, SUM(loss) AS losses, SUM(tie) AS ties
FROM table
GROUP BY (school)
UNION
SELECT score AS round1 FROM table WHERE round=1
UNION
SELECT score AS round2 FROM table WHERE round=2
.... AND so on..
SELECT School, Sum(Case
When Round = 1 Then Score
Else 0
End) AS Round1, Sum(Case
When Round = 2 Then Score
Else 0
End) AS Round2, Sum(Case
When Round = 3 Then Score
Else 0
End) AS Round3, Sum(Case
When Round = 4 Then Score
Else 0
End) AS Round4, Sum(Case
When Round = 5 Then Score
Else 0
End) AS Round5, Sum(Case
When Round = 6 Then Score
Else 0
End) AS Round6, Sum(Case
When Round = 7 Then Score
Else 0
End) AS Round7, Sum(Case
When Round = 8 Then Score
Else 0
End) AS Round8, Sum(Case
When Round = 9 Then Score
Else 0
End) AS Round9, Sum(Case
When Round = 10 Then Score
Else 0
End) AS Round10, Sum(Wins) AS Wins, Sum(Losses) AS Losses, Sum(Ties) AS Ties
FROM MyTable
GROUP BY School
Should work :)
I'm trying to put together a MYSQL query that will count the number of Non-Null (or better yet, non-zero) values in select fields in a single row and then sort from lowest to highest (based on the count). For example, I have a table with 5 fields... ID, Name, Score_1, Score_2, Score_3. I want to count how many times the value "0" exists in Score_1, Score_2 and Score_3 for each record, then sort from most non zero values to least.
ID Name Score_1 Score_2 Score_3
1 Dan 8 7 0
2 Joe 0 0 3
3 Chris 0 0 0
4 Mike 4 5 5
I assume the query has to look something like this...
Select ID, Name, Score_1, Score_2, Score_3 where (???) ORDER BY (???)
Output should look like this (ID 4 is displayed first since it has the least amount of non-zero entries)...
ID Name Score_1 Score_2 Score_3
4 Mike 4 5 5
1 Dan 8 7 0
2 Joe 0 0 3
3 Chris 0 0 0
I'm somewhat new to mysql query's, so any help would be greatly appreciated. I thought the COUNT function would help, but that function appears to count columns from all rows. Perhaps there is a way to use the COUNT function and limit it to a singel row so it can be sorted by that row count?
This should do what you want:
SELECT ID, Name, Score_1, Score_2, Score_3
FROM Table1
ORDER BY (Score_1 = 0) + (Score_2 = 0) + (Score_3 = 0)
Result:
ID Name Score_1 Score_2 Score_3
4 Mike 4 5 5
1 Dan 8 7 0
2 Joe 0 0 3
3 Chris 0 0 0
try This:
Select id, Count1, Count2, Count3, Count4
From
(Select
Sum(Case When IsNull(Score_1,0) = 0 Then 1 Else 0 End) Count1,
Sum(Case When IsNull(Score_2,0) = 0 Then 1 Else 0 End) Count2,
Sum(Case When IsNull(Score_3,0) = 0 Then 1 Else 0 End) Count3,
Sum(Case When IsNull(Score_4,0) = 0 Then 1 Else 0 End) Count4
From Table
Group By Id) Z -- This column (Id) better not be the PK for this table!!!
Order By Count1 + Count2 + Count3 + Count4