I have 5 different columns with over 100 rows each having an assortment of numbers.
I have been able to count all values from column 1 that equal 3
I want to be able to count all the number 3s from all 5 different columns and add them
$countquery = "SELECT COUNT(*) FROM PowerBall WHERE W1=3";
$countresult = mysql_query($countquery) or die(mysql_error());
while($countrow = mysql_fetch_array($countresult)) {
echo "<br />";
echo "There are ". $countrow['COUNT(*)']."-3s";
}
You can use an aggregate function with a CASE expression to get the total number of 3 values in all of your columns.
Select
sum(case when col1 = 3 then 1 else 0 end) TotalCol1,
sum(case when col2 = 3 then 1 else 0 end) TotalCol2,
sum(case when col3 = 3 then 1 else 0 end) TotalCol3,
sum(case when col4 = 3 then 1 else 0 end) TotalCol4,
sum(case when col5 = 3 then 1 else 0 end) TotalCol5
from PowerBall
If you want this in one column, then you can use:
select TotalCol1 + TotalCol2 + TotalCol3 + TotalCol4 + TotalCol5
from
(
Select
sum(case when col1 = 3 then 1 else 0 end) TotalCol1,
sum(case when col2 = 3 then 1 else 0 end) TotalCol2,
sum(case when col3 = 3 then 1 else 0 end) TotalCol3,
sum(case when col4 = 3 then 1 else 0 end) TotalCol4,
sum(case when col5 = 3 then 1 else 0 end) TotalCol5
from PowerBall
) src
Or even:
select sum(Total)
from
(
Select count(col1) Total
from PowerBall
where col1 = 3
union all
Select count(col2)
from PowerBall
where col2 = 3
union all
Select count(col3)
from PowerBall
where col3 = 3
union all
Select count(col4)
from PowerBall
where col4 = 3
union all
Select count(col5)
from PowerBall
where col5 = 3
) src
SELECT SUM(CASE WHEN COL1 = 3 THEN 1 ELSE 0 END) AS 'Col1',
SUM(CASE WHEN COL1 = 3 THEN 1 ELSE 0 END) AS 'Col2',
....
FROM PowerBall WHERE W1 is not null
Related
How can I sum the sum-ed results (goal + delivered) in a new column, in the same query?
SELECT Sum(CASE
WHEN the_status = 'goal' THEN 1
ELSE 0
END) AS goal,
Sum(CASE
WHEN the_status = 'delivered' THEN 1
ELSE 0
END) AS delivered
FROM the_data
where ....
You could just add a third column with both conditions:
SELECT Sum(CASE
WHEN the_status = 'goal' THEN 1
ELSE 0
END) AS goal,
Sum(CASE
WHEN the_status = 'delivered' THEN 1
ELSE 0
END) AS delivered,
Sum(CASE
WHEN the_status IN ('goal', 'delivered') THEN 1
ELSE 0
END) AS goal_and_delivered
FROM the_data
I have a table with some columns (see the pic below):
My Table:
I'd like to count values in that columns (how many "ok" and "no" I have in column over05, over15, etc etc) using some filters (i.e. best_bets between 1.20 and 1.50) and show them using php
Now I can do a count just for a column using code below:
$result=mysql_query("SELECT count(over15) as total from risultati WHERE over15 = 'OK' AND best_bets >= 1.15 AND best_bets <= 1.50");
$data=mysql_fetch_assoc($result);
echo $data['total'];
but I'd like to do it for more columns
Regards
EDIT:I tried in this way, but it's not working:
$result=mysql_query("SELECT SUM(CASE WHEN over05 = 'OK' THEN 1 ELSE 0 END) AS OK_05,
SUM(CASE WHEN over15 = 'OK' THEN 1 ELSE 0 END) AS OK_15,
SUM(CASE WHEN over25 = 'OK' THEN 1 ELSE 0 END) AS OK_25,
SUM(CASE WHEN over35 = 'OK' THEN 1 ELSE 0 END) AS OK_35,
SUM(CASE WHEN over45 = 'OK' THEN 1 ELSE 0 END) AS OK_45
FROM risultati
WHERE best_bets BETWEEN 1.15 AND 1.5O");
$data=mysql_fetch_assoc($result);
echo $data['OK_15'];
echo $data['OK_25'];
echo $data['OK_35'];
echo $data['OK_45'];
edit2: I also tried in another way, but nothing:
$result=mysql_query("SELECT SUM(CASE WHEN over05 = 'OK' THEN 1 ELSE 0 END) AS OK_05,
SUM(CASE WHEN over15 = 'OK' THEN 1 ELSE 0 END) AS OK_15,
SUM(CASE WHEN over25 = 'OK' THEN 1 ELSE 0 END) AS OK_25,
SUM(CASE WHEN over35 = 'OK' THEN 1 ELSE 0 END) AS OK_35,
SUM(CASE WHEN over45 = 'OK' THEN 1 ELSE 0 END) AS OK_45
FROM risultati
WHERE best_bets BETWEEN 1.15 AND 1.5O");
while ($row = mysql_fetch_assoc($result))
{
echo $row['OK_05'];
echo $row['OK_15'];
echo $row['OK_25'];
echo $row['OK_35'];
echo $row['OK_45'];
}
Use condtional aggregation:
SELECT SUM(CASE WHEN over05 = 'OK' THEN 1 ELSE 0 END) AS OK_05,
SUM(CASE WHEN over15 = 'OK' THEN 1 ELSE 0 END) AS OK_15,
SUM(CASE WHEN over25 = 'OK' THEN 1 ELSE 0 END) AS OK_25,
SUM(CASE WHEN over35 = 'OK' THEN 1 ELSE 0 END) AS OK_35,
SUM(CASE WHEN over45 = 'OK' THEN 1 ELSE 0 END) AS OK_45
FROM risultati
WHERE best_bets BETWEEN 1.15 AND 1.5O -- or whatever restrictions you want
This approach allows you to gather stats for all your age columns in a single query, whereas putting the column check for 'OK' limits to a single column in one query.
I am trying to count ads for different price ranges, but my query does not output when count is zero and thus I am unable to relate that to the range array.
Like this:
This is the array with the price breaks:
$arr_pri = array(1, 30000, 50000, 75000, 100000, 125000, 150000, 175000, 200000, 300000, 400000);
It here's the query:
$ctpri = count ($arr_pri);
$ctmod_pri = array();
$arr_i=$arr_k='';
$sql = "SELECT `range`, COUNT(`ad_id`) as ctads FROM (
SELECT CASE ";
for ($i=0; $i < $ctpri-1; $i++){
$k=$i+1;
$arr_i=$arr_pri[$i]+1;
$arr_k=$arr_pri[$k];
$sql .= "WHEN price BETWEEN {$arr_i} AND {$arr_k} THEN CAST('{$i}' AS UNSIGNED) ";}
$sql .= " END AS `range`, ad_id FROM ads
WHERE published = 'Y'
AND deleted = 'N' ) AS t GROUP BY `range`";
$stmt = $ulink->prepare($sql);
$stmt->execute();
while ($r = $stmt->fetch(PDO::FETCH_ASSOC)) {
ctmod_pri[] = $r['ctads'];
}
A typical output for $ctmod_pri is:
array(5) { [0]=> string(1) "1" [1]=> string(1) "2" [2]=> string(1) "1" [3]=> string(1) "1" [4]=> string(1) "1" }
I was expecting it to produce an array with 10 elements, one for each price range ( 0-30000, 30001-50000 ....), also outputting zero results.
What am I missing?
As Michael-sqlbot pointed out the CASE will not do what you want. I'm not entirely sure of the desired output but try this query.
SELECT '2-30000' AS `range`, SUM(CASE WHEN price BETWEEN 2 AND 30000 THEN 1 ELSE 0 END) AS `ctads` FROM ads
union
SELECT '30001-50000' AS `range`, SUM(CASE WHEN price BETWEEN 30001 AND 50000 THEN 1 ELSE 0 END) AS `ctads` FROM ads
union
SELECT '50001-75000' AS `range`, SUM(CASE WHEN price BETWEEN 50001 AND 75000 THEN 1 ELSE 0 END) AS `ctads` FROM ads
union
SELECT '75001-100000' AS `range`, SUM(CASE WHEN price BETWEEN 75001 AND 100000 THEN 1 ELSE 0 END) AS `ctads` FROM ads
union
SELECT '100001-125000' AS `range`, SUM(CASE WHEN price BETWEEN 100001 AND 125000 THEN 1 ELSE 0 END) AS `ctads` FROM ads
union
SELECT '125001-150000' AS `range`, SUM(CASE WHEN price BETWEEN 125001 AND 150000 THEN 1 ELSE 0 END) AS `ctads` FROM ads
union
SELECT '150001-175000' AS `range`, SUM(CASE WHEN price BETWEEN 150001 AND 175000 THEN 1 ELSE 0 END) AS `ctads` FROM ads
union
SELECT '175001-200000' AS `range`, SUM(CASE WHEN price BETWEEN 175001 AND 200000 THEN 1 ELSE 0 END) AS `ctads` FROM ads
union
SELECT '200001-300000' AS `range`, SUM(CASE WHEN price BETWEEN 200001 AND 300000 THEN 1 ELSE 0 END) AS `ctads` FROM ads
union
SELECT '300001-400000' AS `range`, SUM(CASE WHEN price BETWEEN 300001 AND 400000 THEN 1 ELSE 0 END) AS `ctads` FROM ads;
It will count the number of ads in the price range given. You can change the 2-30000 to 0 and so forth if that's the output you need.
The THEN 1 else 0 basically means if the row satisfies the WHEN portion, it says add 1 otherwise add 0.
I want to do math in a query, and was wondering if its better to do it in PHP or MYSQL.
Also, if I choose MYSQL can anyone help me with the query.
So far I have
SELECT COUNT(*) as total, booker, appdate,
SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) book,
SUM(CASE WHEN status!='DNS' THEN 1 ELSE 0 END) tot
FROM appts WHERE WEEK(app_date)= WEEK(CURDATE()) GROUP BY booker
I want one more stat from this query.
I want to do book / (book+tot)
But obviously only if book!=0 or tot!=0, since obviously I don't want to divide anything by zero.
Is there a way to do this in a MYSQL query??
I want my output to be.....
book | 14
tot | 25
hold | 35%
Id also like to ORDER BY the hold percent from highest to lowest. Is this possible????
You can achieve what you ask for using a subquery, like this:
SELECT *, IF(book + tot, 100*book/(book + tot), NULL) AS hold
FROM (
SELECT COUNT(*) as total, booker, appdate,
SUM(status='DNS') book, SUM(status!='DNS') tot
FROM appts WHERE WEEK(app_date)= WEEK(CURDATE()) GROUP BY booker
) AS subquery
ORDER BY hold DESC
Note that in several places I'm using the fact that MySQL uses numbers for logical values. So you can sum up conditions without CASE, and you can write a formula for IF without <> 0 check.
Naive method:
SELECT
COUNT(*) as total,
SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) book,
SUM(CASE WHEN status!='DNS' THEN 1 ELSE 0 END) tot,
IF( ( SUM(CASE WHEN status!='DNS' THEN 1 ELSE 0 END) +
SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) ) = 0,
0,
SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) /
( SUM(CASE WHEN status!='DNS' THEN 1 ELSE 0 END) +
SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) )
) AS hold
FROM appts
WHERE WEEK(app_date) = WEEK(CURDATE()) GROUP BY booker
ORDER BY hold;
Or in order not to repeat your aliases, use a subquery:
SELECT *, IF (book + tot = 0, 0, book / (book + tot) * 100)
FROM (
SELECT
COUNT(*) as total,
SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) book,
SUM(CASE WHEN status!='DNS' THEN 1 ELSE 0 END) tot,
FROM appts
WHERE WEEK(app_date) = WEEK(CURDATE()) GROUP BY booker
) AS subq
ORDER BY hold;
Or, more cleverly :) (book + tot = total)
SELECT *, IF (total = 0, 0, book / total * 100)
FROM (
SELECT
COUNT(*) as total,
SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) book,
SUM(CASE WHEN status!='DNS' THEN 1 ELSE 0 END) tot,
FROM appts
WHERE WEEK(app_date) = WEEK(CURDATE()) GROUP BY booker
) AS subq
ORDER BY hold;
And, just for fun, the hackishly compactest form:
SELECT *, COALESCE(book / total * 100, 0) AS hold -- a division by 0 returns NULL
FROM (
SELECT
COUNT(*) total,
SUM(status='DNS') book, -- boolean "true" is internally integer "1"
SUM(status!='DNS') tot,
FROM appts
WHERE WEEK(app_date) = WEEK(CURDATE()) GROUP BY booker
) AS subq
ORDER BY hold;
$pos = select * from score_history where content_id = 6 && val = 1
$neg = select * from score_history where content_id = 6 && val = -1
i want to get the pos and neg scores in one query
but i dont want to use join
so perhaps some sort of IF/case statement ?
i've this but as you can guess it fails
SELECT count(*) as total ,
CASE
WHEN `val` = 1 THEN count(*) as `pos`
WHEN `val` = -1 THEN count(*) as `neg`
END
FROM score_history WHERE `content_id` = '46083' ";
is there any way to do this without using join or sub query ?
You can make use of the flexibility of MySQL to handle booleans and integers:
SELECT count(*) total, sum(val = 1) pos, sum(val = -1) neg
FROM score_history
WHERE content_id = '46083';
Whenever the condition is true it is a 1. Otherwise a 0. No CASE needed nor GROUP BY.
Close! A CASE statement doesn't return multiple columns, so you'll need 2 CASE statements and to wrap them in a SUM():
SELECT count(*) as total
,SUM(CASE WHEN `val` = 1 THEN 1 ELSE 0 END) as `pos`
,SUM(CASE WHEN `val` = -1 THEN 1 ELSE 0 END) as `neg`
FROM score_history WHERE `content_id` = '46083' ;
SELECT
SUM(CASE WHEN `val` = 1 THEN 1 ELSE O END) AS pos_count,
SUM(CASE WHEN `val` = -1 THEN 1 ELSE O END) AS neg_count
FROM score_history WHERE `content_id` = '46083';
Try this. Sorry I can't test, no database on this laptop.
select
count(*) as total,
sum(case val when 1 then 1 else 0 end) as pos,
sum(case val when -1 then 1 else 0 end) as neg
from score_history
where content_id = 6
Not sure if this is the best answer (and you would certainly want an index on your val column assuming there are many rows in the table) but this should certainly work - also assuming you only have 1 and -1 as values:
SELECT count(*), val from score_history where content_id = 6 group by val;
You were close; try the SUM function:
SELECT count(*) as total
, sum(CASE WHEN `val` = 1 THEN 1 ELSE 0 END) as `pos`
, sum(CASE WHEN `val` = -1 THEN 1 ELSE 0 END) as `neg`
FROM score_history
WHERE `content_id` = '46083';
select count(*)
from score_history
where content_id = 6 &&
(val = -1 or val=1)
group by val
I think this statement should work but I have tested on DBMS.
SELECT count(*) as total ,
count(case when val = 1 then 1 else null end) as pos,
count(case when val = -1 then 1 else null end) as neg
FROM score_history
WHERE `content_id` = '46083';
See SQLFIDDLE
Okay, a lot of these answers are close, but whenever you use an aggregate function you should use a group by.
SELECT count(*) as total
, (CASE WHEN `val` >= 0 THEN 'positive' ELSE 'negative' END) as interpreted_value
END
FROM score_history
WHERE `content_id` = '46083'
GROUP BY (CASE WHEN `val` >= 0 THEN 'positive' ELSE 'negative' END);
If you want to read up on how to use group by and aggregate functions here: https://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html