I have this data:
id date userid result
1 2015-05-01 1 a
2 2015-05-02 1 b
3 2015-05-03 1 b
4 2015-05-03 1 a
5 2015-05-04 1 a
I need to get users sorted by result:
id a b
1 1 1
2 1 1
You want conditional aggregation:
SELECT user_id, sum(result = 'win') AS wins, sum(result = 'loss') as losses
FROM table
GROUP BY user_id
ORDER BY wins DESC
LIMIT 4;
I would do it like this:
SELECT user_id,
SUM(CASE WHEN result='win' THEN 1 ELSE 0 END) AS wins,
SUM(CASE WHEN result='loss' THEN 1 ELSE 0 END) AS losses
FROM table1
GROUP BY user_id
ORDER BY wins DESC
LIMIT 4
Fiddle is here: http://sqlfiddle.com/#!9/00ac7/8
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 want to have a sum of a column that is based if the value of another column is this/that. Here's my table structure
id leave_hours leave_type overtime_hours employee_id
1 7.6 1 0 3
2 5 2 0 3
3 0 0 2.3 3
I have this query already but I need to have a column that will only sum if leave type is 1 and if the leave type is 2
SELECT employee_id, SUM(overtime_hours) AS ot_hrs, SUM(leave_hours if leave_type == 1) AS
leave_1, SUM(leave_hours if leave_type == 2) AS leave_2
FROM table
GROUP BY employee_id
Result should be:
employee_id ot_hrs leave_1 leave_2
3 2.3 7.6 5
Thanks for your inputs.
You need to use conditional aggregation to sum the different leave_hours separately:
SELECT employee_id,
SUM(overtime_hours) AS ot,
SUM(CASE WHEN leave_type = 1 THEN leave_hours ELSE 0 END) AS leave_1,
SUM(CASE WHEN leave_type = 2 THEN leave_hours ELSE 0 END) AS leave_2
FROM `table`
GROUP BY employee_id
Output:
employee_id ot leave_1 leave_2
3 2.3 7.6 5
Demo on dbfiddle
Note that if you use floating point numbers to store the hours, you may need to ROUND the results.
you can use max() with case when
SELECT employee_id,
max(overtime_hours) AS ot,
max(CASE WHEN leave_type = 1 THEN leave_hours END) AS leave_1,
max(CASE WHEN leave_type = 2 THEN leave_hours END) AS leave_2
FROM table_name
GROUP BY employee_id
output
employee_id ot leave_1 leave_2
3 2.3 7.599999904632568 5
Below is my table let's call account
**ID accountID score tracking_date
1 1 3 2014-09-25 00:01:05
2 2 4 2014-09-26 01:05:18
3 1 6 2014-09-27 09:23:05
4 2 9 2014-09-28 20:01:05
5 1 1 2014-09-28 23:21:34
6 3 7 2014-09-21 00:01:00
7 2 1 2014-09-22 01:45:24
8 2 9 2014-09-27 14:01:43
9 3 1 2014-09-24 22:01:27
I want to select record with max date and also the difference of score with the records having tracking_date as minimum for that accountId. So I want output like below
ID accountID score_with_maxdate diff_score_with_mindate max_tracking_date
1 1 1 -2 2014-09-28 23:21:34
2 2 9 8 2014-09-28 20:01:05
3 3 1 -6 2014-09-24 22:01:27
Any help?
Here is one option. We can self-join a subquery which finds both the min and max tracking dates, for each account, twice to your original table. This will bring in all metadata for those max tracking date records, including the scores.
SELECT
t1.accountID,
t2.score AS score_with_maxdate,
t2.score - t3.score AS diff_score_with_mindate,
t1.max_tracking_date
FROM
(
SELECT
accountID,
MAX(tracking_date) AS max_tracking_date,
MIN(tracking_date) AS min_tracking_date
FROM yourTable
GROUP BY accountID
) t1
INNER JOIN yourTable t2
ON t1.accountId = t2.accountID AND t2.tracking_date = t1.max_tracking_date
INNER JOIN yourTable t3
ON t1.accountId = t3.accountID AND t3.tracking_date = t1.min_tracking_date
ORDER BY
t1.accountID;
Demo
This is a somewhat tricky question. I think conditional aggregation is a convenient way to solve the problem:
select min(t.id) as id, t.accountId,
max(case when t.tracking_date = t2.max_td then t.score end) as score_with_maxdate,
max(case when t.tracking_date = t2.max_td then t.score
when t.tracking_date = t2.min_td then - t.score
end) as diff_score_with_mindate,
max(t.tracking_date) as max_tracking_date
from t join
(select t2.accountId, min(t2.tracking_date) as min_td, max(t2.tracking_date) as max_td
from t t2
group by t2.accountId
) t2
on t.accountId = t2.accountId
group by t.accountId;
Another hackish way of getting same results by using aggregate and string fucntion
select t.accountID,
t.score_with_maxdate,
t.score_with_maxdate - t.score_with_mindate score_with_maxdate,
t.max_tracking_date
from(
select accountID,
substring_index(group_concat(score order by tracking_date desc),',', 1) + 0 score_with_maxdate,
substring_index(group_concat(score order by tracking_date asc),',', 1) + 0 score_with_mindate,
max(tracking_date) max_tracking_date
from demo
group by accountID
) t
Demo
But i would suggest you to go with other solutions mentioned by Tim & Gordon
We have the table to track what product page a user visited.
product_tracking
____________________
id user_id product
1 1 A
2 1 B
3 2 A
4 1 A
I know we can use group by user_id, and group_by product but I need both.
Expected result :
result_table
____________________________
user_id A B C
1 2 1 0
2 1 0 0
any idea how to merge the 2 group by ?
You could do this:
SELECT
product_tracking.user_id,
SUM(CASE WHEN product_tracking.product='A' THEN 1 ELSE 0 END) AS A,
SUM(CASE WHEN product_tracking.product='B' THEN 1 ELSE 0 END) AS B,
SUM(CASE WHEN product_tracking.product='C' THEN 1 ELSE 0 END) AS C
FROM
product_tracking
GROUP BY
product_tracking.user_id
An alternative to using sum(...) is using count(...):
SELECT
product_tracking.user_id,
COUNT(CASE WHEN product_tracking.product='A' THEN 1 END) AS A,
COUNT(CASE WHEN product_tracking.product='B' THEN 1 END) AS B,
COUNT(CASE WHEN product_tracking.product='C' THEN 1 END) AS C
FROM
product_tracking
GROUP BY
product_tracking.user_id
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