Counting individual items in MY SQL or MS SQL column - mysql

I have data with column name Rule1 with values ..Correct, Incorrect and Undefined
I was able to get the count of them in this particular column using Group BY
select Rule1, count(*) from table_name group by Rule1;
I have one more column Rule2 with Values Correct, Incorrect only
When I try a similar select statement as above, I am getting the only count of Correct and Incorrect
I want to get the count of Undefined as zero as no Undefined is present in Rule2 column
How to do that
How I can write a query that needs to show the count of fixed values in multiple columns

You can create a derived table that enumerates the possible values with union all, then bring your table with a left join:
select x.rule1, count(t.rule1) cnt
from (select 'Correct' rule1 union all select 'Incorrect' union all select 'Undefined') x
left join mytable t on t.rule1 = x.rule1
group by x.rule1
This is a cross-database syntax that will work in both MySQL and SQL Server.
In very recent versions of MySQL, you can use the values(row ...) syntax:
select x.rule1, count(t.rule1) cnt
from (values row('Correct'), row('Incorrect'), row('Undefined')) x(rule1)
left join mytable t on t.rule1 = x.rule1
group by x.rule1
In SQL Server, the equivalent query is:
select x.rule1, count(t.rule1) cnt
from (values ('Correct'), ('Incorrect'), ('Undefined')) x(rule1)
left join mytable t on t.rule1 = x.rule1
group by x.rule1

You could also use sum like this:
SELECT
sum(case when Rule1 = 'Correct' then 1 else 0 end) AS Rule1Correct,
sum(case when Rule1 = 'Incorrect' then 1 else 0 end) AS Rule1Incorrect,
sum(case when Rule1 = 'Undefined' then 1 else 0 end) AS Rule1Undefined,
sum(case when Rule2 = 'Correct' then 1 else 0 end) AS Rule2Correct,
sum(case when Rule2 = 'Incorrect' then 1 else 0 end) AS Rule2Incorrect
FROM
table_name
WHERE
1
It enables multiple counts in one query. I added all the counts, thought the first two was enough for the idea.
Futhermore I have no idea what is better for the serverload, this or using unions.

Related

How to make this sql query work for multiple columns

I have a query structured like below, it checks if any of the entry in a given column is not null, if it finds a match (a value that is not null) it immediately returns Y, if all values are null it returns N. It works with a column called first_name but I need to make it work for other columns as well i.e last_name, middle_name, preferably all in a single query to save execution time. Y or N must be returned for each of the columns specified.
SELECT CASE
WHEN EXISTS(SELECT *
FROM (patient AS p JOIN patient_score AS s ON p.patient_id=s.patient_id)
WHERE first_name IS NOT NULL)
THEN 'Y'
ELSE 'N'
END AS your_result
I have another query which is an alternative and does the same job (1/0 instead of Y/N). But I don't know how to make it work with multiple columns either. A procedure that could work by supplying multiple column names would work as well.
SELECT COUNT(*) AS fn FROM
(SELECT 1
FROM (patient AS p JOIN patient_score AS s ON p.patient_id=s.patient_id)
WHERE first_name IS NOT NULL
LIMIT 1) AS T;
I think it is the query that you want, you have to add a SELECT element (CASE WHEN SUM(CASE WHEN column_name IS NULL THEN 0 ELSE 1 END) > 0 THEN 'Y' ELSE 'N' END AS column_name) for each column you want to check.
SELECT
CASE WHEN SUM(CASE WHEN first_name IS NULL THEN 0 ELSE 1 END) > 0 THEN 'Y' ELSE 'N' END AS first_name
FROM patient AS p
INNER JOIN patient_score AS s ON p.patient_id = s.patient_id

How to include NULL values in aggregate function COUNT() in MySQL?

The aggregate query groups by attribute A3 and then performs a COUNT(A4) but it doesn't consider the NULL values in the attribute A4.
For a regular count, don't include the column name:
count(*)
For count distinct, just add the extra value back in:
count(distinct a4) + (case when count(a4) <> count(*) then 1 else 0 end)
This can be simplified in MySQL to:
count(distinct a4) + (count(a4) <> count(*))
Or, if you know there is value that won't exist in the column:
count(distinct coalesce(a4, ' <NULL>'))

MySQL select most occurring or average

I have a MySQL table from which I want to select:
1) Either "most occurring" value, if there is any prevailing
2) Or "average" value, if there is no most occurring value.
Example table 1:
value
1
2
3
4
All values are occurred equally, therefore I want to take AVG(`value`)
Example table 2:
value
1
2
2
3
Value 2 prevails, therefore I want to select the value 2.
What mysql query would do this?
Starting from Gordon's answer I tested and corrected the SQL query in SQL Fiddle:
SELECT IF(t4.numcnts = 1, t1.avgvalue, t2.topvalue) AS result
FROM (select avg(value) as avgvalue from test) t1
CROSS JOIN (select value as topvalue from test group by value order by count(*) desc limit 1) t2
CROSS JOIN join (select count(distinct cnt) as numcnts from
(select count(*) as cnt from test group by value) t3) t4
Here is the Fiddle with the two test tables (switch out test2 for test to see the result when a particular value prevails): http://sqlfiddle.com/#!2/76914/3
My changes were to use an IF instead of a CASEstatement in the SELECTclause and to add the necessary table aliases for the subselects.
The following approach calculates both values and then chooses between them:
select (case when numcnts = 1 then avgvalue else topvalue end)
from (select avg(value) as avgvalue from t) cross join
(select value as topvalue from t group by value order by count(*) desc limit 1) cross join
(select count(distinct cnt) as numcnts from (select count(*) as cnt from t group by value))
Note: if you have ties for the top, but other values as well, then an arbitrary value is returned. You don't specify what to do in this case.
Also, the SQL is untested, so it might have syntax errors.

sql query with a count

im sure this is easy but im having a block I am trying to write some sql against a single table that has (simplified for example)
RunName, Result
foo, pass
foo, pass
foo, fail
foo, pass
boo, pass
boo, fail
boo, fail
soo, pass
I was a query that will return a count of pass or fail for each name
something like for fail
foo, 1
boo, 2
soo, 0
and for pass
foo, 3
boo, 1
soo, 1
Normally you'd do a simple COUNT and GROUP BY RunName, but that will not show "zero results" like soo's fails.
This should work even for zero results (on MySQL)
SELECT RunName, SUM(Result='fail')
FROM TableA
GROUP BY RunName;
Demo here.
Edit: As Aaron points out, that only works on MySQL, this works on SQL Server also;
SELECT RunName, SUM(CASE WHEN Result = 'fail' THEN 1 ELSE 0 END) as fails
FROM TableA
GROUP BY RunName
Demo here.
Edit2: As Marcus points out, it's may not be a very index friendly way of doing the query, so if you have a primary key you may be better off doing a self join with a count/group to get the correct result;
SELECT a.RunName, COUNT(b.Result)
FROM TableA a LEFT JOIN TableA b ON a.id=b.id AND b.Result='fail'
GROUP BY RunName
Demo here.
This is for all the fail results, just change the where clause for pass:
select RunName, count(Result)
from [tableName]
where Result = 'fail'
group by RunName
You need to use a group by.
Something like this
Select count(result), runname, result from sometable
group by runname, result
this should give you output like
count runname result
2 foo pass
3 foo fail
Is this what you want?
SELECT RunName, SUM(CASE WHEN Result = 'pass' THEN 1 ELSE 0 END) as NumPass,
SUM(CASE WHEN Result = 'fail' THEN 1 ELSE 0 END) as NumFail
FROM yourtable
GROUP BY RunName
If you want separate results for each then you can just do a filter on the where clause like so:
SELECT RunName, COUNT(1) as NumPass
FROM yourtable
WHERE Result = 'pass'
GROUP BY RunName
SELECT RunName, COUNT(1) as NumFail
FROM yourtable
WHERE Result = 'fail'
GROUP BY RunName
Try this for fail
select RunName, count(Result) as cnt
from your_table
where Result = 'fail'
group by RunName
and this for pass
select RunName, count(Result) as cnt
from your_table
where Result = 'pass'
group by RunName
Try this:
For Pass:
SELECT RunName, COUNT(*)
FROM TableName
GROUP BY Result
WHERE UPPER(Result) = 'PASS'
For Fail:
SELECT RunName, COUNT(*)
FROM TableName
GROUP BY Result
WHERE UPPER(Result) = 'FAIL'

Count the number of times a string occurs in a row with the type SET

My database has got four columns: one, two, three and four each one has the type SET('a','b','c','d').
I want to know how many times a, b, c and d occurs in each column.
I guess I could do something like this
SELECT
(SELECT COUNT(*) FROM database as d WHERE d.a = 'one') AS one,
(SELECT COUNT(*) FROM database as d WHERE d.a = 'two') AS two,
(SELECT COUNT(*) FROM database as d WHERE d.a = 'three') AS three,
(SELECT COUNT(*) FROM database as d WHERE d.a = 'four') AS four
FROM database
LIMIT 1
four times which I know would work. Or I could fetch the entire result and count what's in the array.
Can I somehow do this more efficient?
select one,count(*) from db group by one
select two,count(*) from db group by two
etc
You can combine multiple counts in a single select using case and sum:
SELECT
sum(case when d.a = 'one' then 1 else 0 end) as SumAIsOne
, sum(case when d.b = 'two' then 1 else 0 end) as SumBIsTwo
, <other counts here>
FROM database