SQL - Select all rows and count only column greater than 1 - mysql

Let's say I have this table:
name| value
----|------
A | 0
B | 0
A | 1
C | 1
A | 1
The select I want is to give the result like this:
A | 2
B | 0
C | 1
In first phase I tried with:
SELECT name, count(0)
FROM table
WHERE value > 0
GROUP BY name;
Which result
A | 2
C | 1
I also want to include B with count(0) = 0. How I can do this?

You want to aggregate your rows and get one result row per name. This translates to GROUP BY name in SQL. For counting use COUNT and inside use CASE WHEN to decide what to count.
select name, count(case when value > 0 then 1 end)
from mytable
group by name
order by name;
This works because COUNT only counts non-null occurences. We could just as well use SUM for counting: sum(case when value > 0 then 1 else 0 end).
In your example there is only 0 and 1. If these are the only possible values, you can just add them up:
select name, sum(value)
from mytable
group by name
order by name;

Do you just want aggregation? The following query would actually produce the correct results for your sample data:
select name, sum(value) sum_value
from mytable
group by name

Try this:
SELECT a.name, count(*)*(case when sum(a.value) >= 1 then 1 else 0 end)
FROM table a
GROUP BY name;
For a better solution, give more details about the nature of the value column

Related

group query result in which flag not included

I have a table like this
NAME FLAG
---------------------------
abc 1
abc 0
abc 2
def 1
def 2
xyz 0
xyz 0
xyz 1
efg 1
I need query that list the name (group the result) which flag not included 0 and included 1.The result simply like below:-
NAME FLAG
------------------
def 1
efg 1
I have tried the query but not results the same.
select * mytable where FLAG NOT IN (0) GROUP BY NAME;
This is the simplest solution I can come up with. I believe there are more elegant answers possible.
SELECT *
FROM mytable
WHERE name NOT IN (SELECT name FROM mytable WHERE flag = 0)
AND flag = 1;
You can use NOT EXISTS clause in this way.
select a.*
from tbl a
where not exists
(select *
from tbl b
where b.name=a.name
and b.flag=0)
and a.flag=1;
We can use aggregation. The trick is to run a condition on each row, and then use an aggregate function to pick out the net result of the condition from all of the rows...
SELECT t.name
FROM a_table_like_this t
GROUP BY t.name
HAVING MAX(t.flag=0) <> 1
AND MAX(t.flag=1) = 1
The expressions in the HAVING clause are MySQL shorthand.
A more ANSI standards compliant equivalent would be:
SELECT t.name
FROM a_table_like_this t
GROUP BY t.name
HAVING MAX( CASE WHEN t.flag=0 THEN 1 ELSE 0 END) <> 1
AND MAX( CASE WHEN t.flag=1 THEN 1 ELSE 0 END) = 1
To get a better handle on what this is doing, take a look at how those expressions are evaluated on each row. Remove the GROUP BY clause, and move those expressions into the SELECT list...
SELECT t.name
, t.flag
, CASE WHEN t.flag=0 THEN 1 ELSE 0 END AS `fl=0`
, CASE WHEN t.flag=1 THEN 1 ELSE 0 END AS `fl=1`
FROM a_table_like_this t
ORDER
BY t.name
, t.flag
We get something like
name flag fl=0 fl=1
------ ---- ---- ----
abc 1 0 1
abc 0 1 0
abc 2 0 0
def 1 0 1
def 2 0 0
xyz 0 1 0
xyz 0 1 0
xyz 1 0 1
efg 1 0 1
If we now aggregate these rows by name (GROUP BY name), we can use MAX() aggregate to pick out a 1 (if there's one in the group. Otherwise, we'll get back a 0.)
And we can do conditional tests on the results of aggregates functions in the HAVING clause.

MySQL: Retrieve Values and Counts For Each

How can I count the occurrence of the field/column in SQL?
Example dataset:
A
A
A
A
B
B
C
I want:
A | 4
A | 4
A | 4
A | 4
B | 2
B | 2
C | 1
Is there anyway to do it without using GROUP BY? So far all answer I get my query retuns the following:
A | 4
B | 2
C | 1
select value, count(*) from table group by value
Use HAVING to further reduce the results, e.g. only values that occur more than 3 times:
select value, count(*) from table group by value having count(*) > 3
You could use a nested sub-select for this desired result set.
If the example table name is my_table and the column called col1:
select col1,
(select count(*) from my_table where col1 = t.col1) as Count
from my_table t;
Or if you want to remove the duplicates, use the distinct statement. It removes the duplicates of your result set.
select distinct col1,
(select count(*) from my_table where col1 = t.col1) as Count
from my_table t;

How to get the sum of a value in MySQL table

Let's say I've a mysql table properties with these records:
---------------------------------
id value
---------------------------------
1 1
1 1
2 1
2 1
1 1
---------------------------------
Now, I want to query to output:
----------------------------
id value
----------------------------
1 3
2 2
----------------------------
Try this
select id,sum(value) as value FROM table group by id
And this is what you want:
select id, sum(value) as value from properties group by id
You need to use the GROUP BY parameter.
SELECT id, SUM(value) as value FROM tablename GROUP BY id
Use This Code
SELECT id, sum(value) AS value FROM `tablename ` Group by id;

Count Duplicates with same id passing in one coulmn

Hi there m trying to calculate the row count for same value,
id,value
1 | a
2 | b
3 | c
4 | d
5 | e
and my query is
select value, count(*) as Count from mytable where id in('4','2','4','1','4') group by value having count(*) > 1
for which my expected output will be,
value,Count
d | 3
b | 1
a | 1
Thanks, any help will be appreciated
Try that:
SELECT value, count(value) AS Count
FROM mytable m
WHERE value = m.value
GROUP BY value
SELECT t.id, t.value, COUNT(t.id)
FROM
test t
JOIN
( SELECT 1 AS id
UNION ALL SELECT 3
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 1
UNION ALL SELECT 1 ) AS tmp
ON t.id = tmp.id
GROUP BY t.id
Sample on sqlfiddle.com
See also: Force MySQL to return duplicates from WHERE IN clause without using JOIN/UNION?
Of course, your IN parameter will be dynamic, and thus you will have to generate the corresponding SQL statement for the tmp table.
That's the SQL-only way to do it. Another possibility is to have the query like you have it in your question and afterwards programmatically associate the rows to the count passed to the IN parameter.

Count by ratio and then group by MSQL

I have a table like
ID Name
1 ABC
1 DEF
1 VVV
1 BBB
1 BCD
2 ZZZ
2 BAA
3 AAA
3 BBB
3 BBC
I want to get the ratio of all the names that start with A to All the names that start with B group by ID.
So the output should be
ID Ratio
1 0.5
2 0
3 0.33
.
SELECT (ID, (SELECT COUNT(*) FROM `table` WHERE name LIKE 'A%') /
(SELECT COUNT(*) FROM `table` WHERE name LIKE 'B%')) AS `ratio` from table Group by ID
does not give me the right answer. It takes the total ratio of A/B across all ID's into account and writes that number for all the ID's.
I'd try:
SELECT ID, CASE WHEN B = 0 THEN 0 ELSE A/B END AS Ratio FROM
( SELECT ID,
SUM(CASE WHEN Name LIKE 'A%' THEN 1 ELSE 0 END) AS A,
SUM(CASE WHEN Name LIKE 'B%' THEN 1 ELSE 0 END) AS B
FROM my_table GROUP BY ID ) AS grouped;
The inner SELECT gets the group IDs, and for every ID, the number of items beginning with A and those beginning with B.
The outer SELECT (you can omit it if you're sure that there'll always be at least one B-row) checks that the ratio makes sense before attempting to calculate it.
Or else:
SELECT ID, COALESCE(SUM(CASE WHEN Name LIKE 'A%' THEN 1 ELSE 0 END)
/ SUM(CASE WHEN Name LIKE 'B%' THEN 1 ELSE 0 END), 0)
FROM my_table GROUP BY ID;
This takes advantage of the fact that, if the number of B-rows is zero, the division will yield NULL. The COALESCE transforms that NULL in a 0.
This will do it:
SELECT
id,
SUM(IF(name LIKE 'A%',1,0))/SUM(IF(name like 'B%',1,0))
FROM `table`
GROUP BY ID