Mysql query for counting winnings and losings - mysql

I have a table with some columns. One of the column registers if the row is true or false. E.g if you lost the game, this is set to 0 else 1.
What I want to count is the amount of 1 in row. The table looks like this:
+-----------+
|game_status|
|-----------|
|00000000 |
|-----------|
|00000000 |
|-----------|
|00000001 |
|-----------|
|00000001 |
|-----------|
|00000001 |
|-----------|
| ... |
+-----------+
So if you count it by hand the result would be:
starting from 0:
lost(0) -> 0 - 1 =
lost(0) -> -1 - 1 =
won(1) -> -2 + 1 =
won(1) -> -1 + 1 =
won(1) -> 0 + 1 =
Result = 1
So how do I get this result using mysql queries? I have tried using count but it counts all ones or zeros.
Thanks in advance.
I think I got a little bit confused when I accepted the answer and I do apologize for that. What I think I forgot to say is the result of the query should look like this:
+--------+------+
| 1 | -1 |
|--------|------|
| 2 | -2 |
|--------|------|
| 3 | -1 |
+---------------+
There the incremental column is the amount of games played...

You could count the wins and subtract the count of the loses.
select (select count(status) from table1 where status = 1) -
(select count(status) from table1 where status = 0)

try:
SELECT COUNT(DISTINCT CASE WHEN Column = 0 THEN 1 END) AS TotalZeros,
COUNT(DISTINCT CASE WHEN Column = 1 THEN 1 END) AS TotalOnes
FROM YourTable
Or much simpler way is if your column only holds either 0 or 1 just select count of either one of them and subtract it from the total rows which will give you the count of other.

Use SUM instead of COUNT. COUNT finds the number of items regardless of their value, SUM actually totals up the integer values.
Look here for reference
http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html

SELECT sum(CASE game_status WHEN 1 THEN 1 ELSE -1 end) FROM table_name;

Related

mysql sum, CASE WHEN with GROUP BY

In MySQL, I want to sum the values ​​of certain statuses and display them in the same count column,
Do I have to give a condition to count ?!
status is 0, 1, 2 and 3, and status = 2 is a sum of 2, 3, 4 count values.
What kind of conditions should I give?
My Query:
SELECT A.STATUS, B.COUNT, B.REG_DT FROM
(SELECT 0 AS STATUS UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) A
LEFT JOIN (
SELECT STATUS , COUNT(*) AS COUNT, FROM TB_EXE WHERE reg_dt >= CURDATE()
GROUP BY STATUS
) B ON A.STATUS = B.STATUS
My Data:
status | count
-----------------
0 | 1
-----------------
1 | 2
-----------------
2 | 1
-----------------
3 | 0
-----------------
4 | 2
Expected Results:
status | count
-----------------
0 | 1
-----------------
1 | 2
-----------------
2 | 3
SELECT STATUS,COUNT(*)
FROM T
WHERE STATUS < 2
GROUP BY STATUS
UNION ALL
(SELECT 2,COUNT(*)
FROM T
WHERE STATUS >= 2
)
Where the 2 aggregations are dealt with separately.
+--------+----------+
| STATUS | COUNT(*) |
+--------+----------+
| 0 | 1 |
| 1 | 1 |
| 2 | 3 |
+--------+----------+
3 rows in set (0.00 sec)
Or more succinctly
select case when status > 1 then 2 else status end, count(*)
from t
group by case when status > 1 then 2 else status end
you can try like below using case when
select case when status>1 then 2 else status end as status,
sum(count) as cnt from t
group by status
Hmmm, I think I'd go with a framing solution on this one. IE something like this:
SELECT
Status,
Count,
SUM(Count) OVER(ORDER BY status ROWS
BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW) AS FramedCount
FROM Status
this gives you a running total of the counts from all previous rows as the framed count. You can handle the logic in the application to determine which statuses should use the framed count OR you could handle it in the query by adding the following.
SELECT
status,
CASE
when status <= 3 THEN count
ELSE SUM(count) OVER(ORDER BY status ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
END AS 'MyCount'
FROM statusInfo

Getting Corresponding Row Values to a GROUP BY with MIN

I've got data that's something like this:
+------------+---------+-------+
| Name | Time | Flag |
+------------+---------+-------+
| Bob | 401 | 1 |
| Bob | 204 | 0 |
| Dan | 402 | 1 |
| Dan | 210 | 0 |
| Jeff | 204 | 0 |
| Fred | 407 | 1 |
| Mike | 415 | 1 |
| Mike | 238 | 0 |
+------------+---------+-------+
I want to get each person's best time, but if the "flag" is set, their time should be divided by 2.
For example, Bob's best time would be 200.5
Now I can do a relatively simple query to get this data like this:
SELECT userid,
MIN(CASE WHEN flag = 1 THEN time / 2 ELSE time END) AS convertedTime,
time,
flag
FROM times t
GROUP BY userid
ORDER BY convertedtime ASC
The problem here is that is doesn't return the proper corresponding data for the time and flag, getting this data:
Bob 200.5 204 0
instead of the correct data
Bob 200.5 401 1
Of course I see the issue with the previous query and I've fixed it with this:
SELECT userid,
MIN(convertedtime) AS convertedTime,
(SELECT time
FROM times
WHERE MIN(convertedtime) = CASE
WHEN flag = 1 THEN time / 2
ELSE time
end
LIMIT 1) AS time,
(SELECT flag
FROM times
WHERE MIN(convertedtime) = CASE
WHEN flag = 1 THEN time / 2
ELSE time
end
LIMIT 1) AS flag
FROM (SELECT userid,
CASE
WHEN flag = 1 THEN time / 2
ELSE time
end AS convertedTime,
time,
flag
FROM times t) AS t
GROUP BY userid
ORDER BY convertedtime ASC
SQLFiddle
This does work, but I feel like there has to be a better and more efficient way of doing this. In my actual query, the part where I'm dividing the time by 2 is a much longer formula and I've got thousands of rows so it's very slow.
So the question is, is there a better/more efficient query for this?
Use a common technique from SQL select only rows with max value on a column but add the flag check when comparing the values in the ON condition.
SELECT t1.username, t2.convertedtime, t1.time, t1.flag
FROM times AS t1
JOIN (SELECT username,
MIN(IF(flag = 1, time/2, time) AS convertedtime
FROM times
GROUP BY username) AS t2
ON t1.username = t2.username
AND t1.time = IF(t1.flag = 1, t2.convertedtime * 2, t2.convertedtime)
This probably won't be very efficient -- I don't think it will be able to use an index for the conditional comparison.
This is what I ended up using (couldn't multiply by 2 to revert the number in this case due to my more complicated actual query having rounding in it), but Barmar did pretty much the same thing as I'm doing so I marked his as the answer.
SELECT times.userID, times2.convertedTime, times.time, times.flag
FROM times JOIN
(
SELECT userid,
MIN(CASE WHEN flag = 1 THEN time / 2 ELSE time END) AS convertedTime,
time,
flag
FROM times t
GROUP BY userid
ORDER BY convertedtime ASC
) as times2 ON times.userid = times2.userid AND
(
(times.time / 2 = times2.convertedTime AND times.flag = 1) OR
(times.time = times2.convertedTime AND times.flag = 0)
)

How to get number of half centuries, centuries and double hundreds for each player in MySQL

I have table with this format
id| name | types |
_________________
1 sachin 100
2 virat 50
3 sachin 50
4 sachin 50
5 sachin 200
6 virat 100
7 virat 200
What I want to get as the result is now something like
name | num of 50 |num of 100 |num of 200
sachin | 2 | 1 | 1
virat | 1 | 1 | 1
What is the correct way to get here ??
I tried using group by. But I didn't get there
Any help?
Thanks
Also you can rely on MySQL boolean expression.
SELECT
name,
SUM(types = 50) as num_50,
SUM(types = 100) as num_100,
SUM(types = 200) as num_200
FROM yourtable
GROUP BY name
Note:
Since MySQL boolean expression resolves into 0/1 so that you can use it inside SUM()
SUM(a=b) returns 1 only if a is equal to b
Working demo
More:
And if you use COUNT as mentioned in #JPG's answer then keep in mind the following subtleties of COUNT
Some subtleties regarding COUNT:
SELECT COUNT(0); Result: 1
SELECT COUNT(-1); Result: 1
SELECT COUNT(NULL); Result: 0
SELECT COUNT(71); Result: 1
SQL FIDDLE
If you just have these types, you can try this:
select
name,
count(case when types = 50 then 1 else null end) as num_50,
count(case when types = 100 then 1 else null end) as num_100,
count(case when types = 200 then 1 else null end) as num_200
from yourtable
group by name
Demo Here

Mysql increment value on multiple cases to order by

I have a table with products, and by answering a set of questions (Could be 2 or could be six, it's not always the same) I want to get results. Each answer has rules to it like color = green or noise > 69.
Now I don't want to use these rules as a WHERE to refine my searchresults, but I want to increment a variable on CASE so I can ORDER on the amount of true conditions. I still get all values, but the ones that better suit my customers needs are on top.
I tried a lot already, something like:
SELECT a.*, b.*,COUNT(CASE WHEN (b.noise >= 1600) THEN 1 ELSE 0 END) as condition_true
But I cant get it to work with multiple CASES.
SAMPLE DATA:
Products table:
id | title
1 | washing machine X
2 | Washing Machine Y200
3 | Even cooler washing machine
Productinfo table
id | noise | color | locked | product_id
1 | 40 | white | 1 | 1
2 | 68 | green | 0 | 2
3 | 72 | green | 1 | 3
Possible rules I will use in the output table
b.noise > 42
b.color = "green"
b.locked = 1
I would love an output table like this
product_id | title | condition_true
3 | Even cooler washing machine | 3
2 | Washing Machine Y200 | 2
1 | washing machine X | 1
CASE only returns one value, and COUNT requires multiple rows. You could just add them.
SELECT a.*, b.*, (CASE WHEN b.noise >= 1600 THEN 1 ELSE 0 END) +
(CASE WHEN color = 'green' THEN 1 ELSE 0 END) AS relevance
FROM table1
ORDER BY relevance DESC
Or, abbreviated for MySQL:
SELECT a.*, b.*, (b.noise >= 1600) +
(color = 'green') AS relevance
FROM table1
ORDER BY relevance DESC
COUNT is not what you want, that works to aggregate results from multiple rows when using GROUP BY.
I would do this using a series of IF() statements, returning 1 or 0 based on the condition (you could also return a bigger number, for more important columns or something):
SELECT IF(b.noise >= 1600,1,0)+IF(b.ocl1 <= 3,1,0)+...;

Count considering sum of 3 columns

I have 3 column (prod1 , prod2 , prod3 ) with TYPE : DOUBLE
id | prod1 | prod2 | prod3 |
1 | 1.3 | 2.6 | 2.8 |
2 | 0.8 | 3.4 | 0 |
3 | 0 | 0 | 1.3 |
4 | 0 | 0 | 0 |
What I want is COUNT() of 3 columns
SELECT count(prod1,prod2,prod3) AS allc
FROM `testprd`
WHERE id =3
I know above code is wrong
SHOULD GIVE RESULT
allc
-------
1
As prod1 and prod2 have 0 values
Similarly when id = 4 count should be 0 as all column for resp id have zero value ,but when id = 1 then count should be 3
Hence I taught count for each id columns and then sum of all , will result me solution but am not able to reach it.
BELOW IS WHAT I HAVE TRIED
SELECT count(prod1) AS a,
count(prod2) AS b,
count(prod3) AS c
FROM `testprd`
WHERE id =3
Result:
a | b | c
-------------
1 1 1
But should be:
a | b | c
-------------
0 0 1
So sum(a+b+c) = 1
Hence count for id = 3 is 1
What am I doing wrong?
You could get the result you want to have with
SELECT
(prod1 !=0 ) + (prod2 != 0) + (prod3 != 0) AS allc
FROM `testprd`
WHERE id = 3
The aggregate function COUNT counts rows in a table or not null rows in a certain column, but not the values that are not equal zero in a set of columns.
COUNT(expr)
Returns a count of the number of non-NULL values of expr in the rows
retrieved by a SELECT statement. The result is a BIGINT value.
COUNT() returns 0 if there were no matching rows.
Use
SELECT id, if(prod1+prod2+prod3>0,1,0) from testprd;
For all columns separated it should be:
SELECT id, if(prod1>0,1,0), if(prod2>0,1,0), if(prod3>0,1,0) from testprd;
Use a simple query like this
SELECT
IF(prod1 > 0,1,0)+IF(prod2 > 0,1,0)+IF(prod3 > 0,1,0) as Total
FROM test
WHERE id = 3;
SQL Fiddle Demo
OUTPUT
| TOTAL |
|-------|
| 1 |
Just check if that product is different from zero then sum all counts like:
SELECT if(prod1!=0,1,0) +
if(prod1!=0,1,0) +,
if(prod1!=0,1,0) AS ct
FROM `testprd`
WHERE id =3
How about:
SELECT
count(*) AS allc FROM `testprd`
WHERE
id =3 AND
0 < ANY (prod1, prod2, prod3);
COUNT counts the rows slected by your SELECT statement, it does not sum up the column values.
SELECT prod1 + prod2 + prod3 AS mySum
FROM `testprd`
WHERE id =3;
See the MySQL doc concerning Arithmetic Operators and COUNT