Display sum of each element in a column using sql? - mysql

I have simple data from database looks like this
ID sid targetbuttonname
1 ab23sve Yes
2 ab23sve Yes
3 ab23sve Yes
4 ab23sve Yes
5 z32b2367 no
6 zb23sve no
7 pb23sve Yes
I want to display the sum of session, the sum of yes, the sum of no using sql;
eg sum of yes should be 5 etc
I tried something like this
select sum(sid), count(targetbuttoname) as yes, count(targetbuttoname) as no from events
What is the right way to display what I want?

Presumably, you want to count these things. So, I would guess:
select count(*) as num_rows,
count(distinct sid) as num_sessions,
sum( targetbuttonname = 'yes' ) as num_yes,
sum( targetbuttonname = 'no' ) as num_no
from events;
Here is a db<>fiddle.

if you want to count number of yes and no then you can use case when
select sum(case when targetbuttoname='yes' then 1 else 0 end) as yes,
sum(case when targetbuttoname='no' then 1 else 0 end) as no from events

Related

SQL pivot column names and organize by date

I have a table as such:
date | page
----- |-----
2018-01-01 | good
2018-01-01 | good
2018-01-01 | good
2018-01-01 | bad
2018-01-02 | good
How do I organize by the values in the page column by date as such:
date | good | bad
----- |------|----
2018-01-01 | 3 | 1
2018-01-02 | 1 | 0
You need conditional aggregation :
select date,
sum(case when page = 'good' then 1 else 0 end) as good,
sum(case when page = 'bad' then 1 else 0 end) as bad
from table t
group by date;
However, MySQL has shorthand for this :
select date,
sum( page = 'good') as good,
sum( page = 'bad' ) as bad
from table t
group by date;
This can work just add a case inside sum function:
select date,
sum( case when page = 'good' then 1 else 0 end) as good,
sum( case when page = 'bad' then 1 else 0 end ) as bad
from table t
group by date
Using pivot table as,
create table #pivot(date date,page varchar(20))
insert into #pivot values
('2018-01-01','good')
,('2018-01-01','good')
,('2018-01-01','good')
,('2018-01-01','bad')
,('2018-01-02','good')
select date,good,bad from(
select date, page from #pivot
) f
pivot
( count(page) for page in (good,bad)
) p
I'm not sure what platform you are using but if it is in Oracle this will do the same.
select date, sum(decode(page,'good',1,0)) as good, sum(decode(page,'bad',1,0)) as bad
from table t
group by date;

Make a calculation with aliases in one (sub)query

I have a table with data and am trying to make the following calculation in a query: IDO / IDP * 100.
**TBL**
Name IDP IDO
ABC 123 231
DEF 124 NULL
GHI 125 NULL
JKL 126 342
KNM 127 NULL
I managed to count up all the values needed to make the calculation and gave each an alias. This is what I have so far, but the calculation part returns an error telling me the references are not supported.
SELECT
SUM(case when IDP is not null then 1 end) as Checked,
SUM(case when IDO is null then 1 end) as NotChecked,
(SELECT Checked / NotChecked) * 100 AS Result
FROM TBL
I've also tried with a subquery, but it results in the same error.
SELECT
SUM(case when IDP is not null then 1 end) as Checked,
SUM(case when IDO is null then 1 end) as NotChecked,
(
SELECT Checked / NotChecked * 100 AS Result FROM TBL
)
FROM TBL
What would be the right or a better way to do this?
I don't think you will be able to reference aliases created in a SELECT clause in that same SELECT clause.
As you probably know, you could just repeat the logic, like the following (although I assume the purpose of your question is to avoid writing the logic twice).
SELECT
SUM(case when IDP is not null then 1 end) as Checked,
SUM(case when IDO is null then 1 end) as NotChecked,
(SUM(case when IDP is not null then 1 end) / SUM(case when IDO is null then 1 end)) * 100 AS Result
FROM TBL
A subquery version, where you don't repeat the logic, would be the following. Note that the aliases are created in the subquery so the outer query has no trouble referencing them.
SELECT
Checked, NotChecked, (Checked / NotChecked) * 100 as Result
FROM
(
SELECT
SUM(case when IDP is not null then 1 end) as Checked,
SUM(case when IDO is null then 1 end) as NotChecked
FROM TBL
) tt
Since you don't seem to be summing, just counting null/non-null values, I personally find the sum/case statements a bit confusing and might prefer something like this:
SELECT
Checked, NotChecked, (Checked / NotChecked) * 100 as Result
FROM
(
SELECT
count(IDP) as Checked,
count(*)-count(IDO) as NotChecked
FROM TBL
) tt

MYSQL Row Count if criteria is met

Sorry but I am not sure how to phrase this question or if it is possible but basically I am using a select statement in which I would like to display a column showing a count of when a criteria is met. For example
SELECT pageID, isHome, if(ishome = 1, 'count?', 0) AS Passed
FROM pages
I would like the passed column to show a running count kind of like this
PageID | ishome | passed
10031 | 0 | 0
10032 | 1 | 1
10033 | 1 | 2
10034 | 1 | 3
Thank you for any help
Try something like the following (untested)
select a.pageid, a.ishome, sum(b.ishome) passed
from
pages a join pages b
on a.pageid>= b.pageid
group by a.pageid, a.ishome
order by a.pageid
Not sure but I think this is want you want.
SELECT pageID, isHome,
case when(ishome = 1)
then count(*)
else 0
end Passed FROM Table1
group by pageID;
sqlfiddle
OR if you want the number of passed pages
SELECT isHome,
case when(ishome = 1)
then count(*)
else 0
end Passed FROM Table1
group by isHome;
sqlfiddle
SELECT pageID, isHome, count(*) AS Passed
FROM pages
where ishome = 1
GROUP BY PageID
DEMO
if you want show all result then use this
SELECT pageID, isHome, if(ishome = 1, count(*), 0) AS Passed
FROM pages
group by pageID,ishome ;
DEMO
Try something like this
SELECT pageID, isHome,
CASE isHome
WHEN 1 THEN SELECT COUNT(*) FROM pages p
WHERE p.isHome = 1 AND p.pageID <= pageID
ELSE 0
END as passed
FROM pages
ORDER BY pageID ASC

something like "group by" for columns?

I have table like this:
+----+---------+---------+--------+
| id | value_x | created | amount |
+----+---------+---------+--------+
value_x is set of six strings, lets say "one", "two", "three", etc.
I need to create report like this:
+--------------+-------------------------+-------------------+----------------------+
| day_of_month | "one" | "two" | [etc.] |
+--------------+-------------------------+-------------------+----------------------+
| 01-01-2011 | "sum(amount) where value_x = colum name" for this specific day |
+--------------+-------------------------+-------------------+----------------------+
Most obvious solution is:
SELECT SUM(amount), DATE(created) FROM `table_name` WHERE value_x=$some_variable GROUP BY DATE(created)
And loop this query six times with another value for $some_variable in every iteration, but I'm courious if is it possible to do this in single query?
What you're asking is called a "pivot table" and is typically achieved as below. The idea is for each potential value of value_x you either produce a 1 or 0 per row and sum 1's and 0's to get the sum for each value.
SELECT
DATE(created),
SUM(CASE WHEN value_x = 'one' THEN SUM(amount) ELSE 0 END) AS 'one',
SUM(CASE WHEN value_x = 'one' THEN SUM(amount) ELSE 0 END) AS 'two',
SUM(CASE WHEN value_x = 'one' THEN SUM(amount) ELSE 0 END) AS 'three',
etc...
FROM table_name
GROUP BY YEAR(created), MONTH(created), DAY(created)
This will come close:
SELECT
s.day_of_month
,GROUP_CONCAT(CONCAT(s.value_x,':',s.amount) ORDER BY s.value_x ASC) as output
FROM (
SELECT DATE(created) as day_of_month
,value_x
,SUM(amount) as amount
FROM table1
GROUP BY day_of_month, value_x
) s
GROUP BY s.day_of_month
You will need to read the output and look for the value_x prior to the : to place the items in the proper column.
The benefit of this approach over #Michael's approach is that you do not need to know the possible values of field value_x beforehand.

counting null data in MySQL

let say i have one table, which have data like:
name status
bob single
bob single
jane null
tina null
shane married
i want if status "single or data null" it means single. so if data empty script can read it as single and can count together.
so i can show result like:
Single Married
3 1
i have tried with this and it doesnt work:
SELECT SUM(IF(status='single',1,0)) AS Single,
SUM(IF(status='married',1,0)) AS Married
FROM table
Use:
SELECT SUM(CASE WHEN x.status = 'single' OR x.status IS NULL THEN 1 ELSE 0 END) AS single,
SUM(CASE WHEN x.status = 'married' THEN 1 ELSE 0 END) AS married
FROM (SELECT DISTINCT
t.name,
t.status
FROM YOUR_TABLE t) x
If you know there are only 'single', 'married', and null as options, this will work:
SELECT SUM(IF(status!='married',1,0)) AS Single,
SUM(IF(status='married',1,0)) AS Married
FROM table
Otherwise try
SELECT SUM(IF(status='single' OR status is null,1,0)) AS Single,
SUM(IF(status='married',1,0)) AS Married
FROM table
SELECT SUM(IF(status='single' OR status IS NULL,1,0)) AS Single,
SUM(IF(status='married',1,0)) AS Married
FROM table