Mysql multi count in one query - mysql

How can I count records for two columns in one table using different query criteria?
Table looks like:
user_id | date | status
------------------------------
1 | 2011-01-02 | 1
2 | 2011-01-03 | 1
3 | 2011-01-02 | 0
4 | 2011-01-03 | 1
1 | 2011-01-02 | 1
I want to count two values in one query. The first one is number of user_id group by status and the second is count of user_id group by date.
How can I do that?

You can't have different GROUP BY clauses in the same query -- each count will have to be in an independent query.
But you can return the output in a single query/resultset using subselects (subquery in the SELECT clause):
SELECT COUNT(a.user_id) AS numUsersPerStatus,
(SELECT COUNT(b.user_id)
FROM YOUR_TABLE b
GROUP BY b.date) AS numUsersPerDate
FROM YOUR_TABLE a
GROUP BY a.status

You don't.
You should use two queries. There's no advantage to doing this with a single query.
If you really want to do it you can try this:
SELECT 'date' AS grptype, date AS grp, COUNT(DISTINCT user_id) AS cnt
FROM yourtable
GROUP BY date
UNION ALL
SELECT 'status' AS grptype, status AS grp, COUNT(DISTINCT user_id) AS cnt
FROM yourtable
GROUP BY status
Result:
grptype grp cnt
date 2011-01-02 2
date 2011-01-03 2
status 0 1
status 1 3
However I would strongly advise against doing this. You want two different and unrelated result sets so you should use two separate queries.

Related

How to find the count of a particular number that can exist in 2 columns

I have a table that consist of a table that describes calls. Hence there is a to column and a from column. The problem is that I want the total messages sent by each number, which can be from or to. Refer to the table above for visuals.
I want the final table to be somethng that shows A : 3 , B: 2 , C:1 and D:1.
How do u count the numbers in 2 columns and sum them up?
One solution would be to first UNION ALL two aggregate queries to gather the count of occurences of each value in the two different columns, and them sum the results in an outer query, like:
SELECT val, SUM(cnt) cnt
FROM (
SELECT `from` val, COUNT(*) cnt FROM mytable GROUP BY `from`
UNION ALL
SELECT `to`, COUNT(*) FROM mytable GROUP BY `to`
) x
GROUP BY val
This demo on DB Fiddle with your sample data returns:
| val | cnt |
| --- | --- |
| A | 3 |
| B | 2 |
| C | 1 |
| D | 1 |
| E | 1 |
You can unpivot the data and aggregate:
select person, count(*) as num_calls
from ((select from as person from t) union all
(select to as person from t
) c
group by person;
Note that from and to are really, really bad names for columns because they are SQL keywords. I haven't escaped them in the query, because that just clutters the query and I assume the real columns have better names.

How do I count the number of rows that have different dates

I want to count the total numbers of row in SQL database.
"tableA" :
id | date |
---+------------+
1 | 2019-09-03 |
2 | 2019-09-03 |
3 | 2019-09-04 |
4 | 2019-09-05 |
I want to execute it as new column name "total" that should have like this :
total
-----
3
because they are 3 different dates.
I know that the result must use 2 query like this:
SELECT date
FROM tableA
GROUP BY date AS total;
SELECT COUNT(total)
FROM tableA;
How to combine 2 queries like that or there is another way?
Use count(distinct date)
SELECT COUNT(distinct date) FROM tableA
select count( distinct date) as total from tableA;

SUMing the results of a COUNT() in MySQL

Is a UNION query required to achieve the following. I have a table with data that looks like this:
some_id | some_date
--------------------
5 | 2016-04-03
3 | 2016-04-03
2 | 2016-04-03
5 | 2016-04-03
I'd like to get the total number of times we've seen any and all ID for the date 2016-04-03. So the SUM would be 3 here, with 5 having a count of 2, 3 having a count of 1, 2 having a count of 1.
Is a UNION required to make this work?
This is using MySQL 5.6+
Use COUNT(DISTINCT):
SELECT COUNT(DISTINCT some_id)
FROM YourTable
WHERE some_date = '2016-04-03'
I do not think this requires a UNION
SELECT some_id, SUM(1) as cnt, some_date
FROM some_table
GROUP BY some_id, some_date
WITH ROLLUP
Here is a test.

select non group by columns with count in Mysql

I have a table tbl with three columns:
id | fk | dateof
1 | 1 | 2016-01-01
2 | 1 | 2016-01-02
3 | 2 | 2016-02-01
4 | 2 | 2016-03-01
5 | 3 | 2016-04-01
I want to get the results like this
Id count of Id max(dateof)
2 | 2 | 2016-01-02
4 | 2 | 2016-03-01
5 | 1 | 2016-04-01
My try
SELECT id,tbl.dateof dateof
FROM tbl
INNER JOIN
(SELECT fk, MAX(dateof) dateof ,
count(id) cnt_of_id -- How to get this count value in the result
FROM tbl
GROUP BY fk) temp
ON tbl.fk = temp.fk AND tbl.dateof = temp.dateof
This is an aggregation query, but you don't seem to want the column being aggregated. That is ok (although you cannot distinguish the rk that defines each row):
select count(*) as CountOfId, max(dateof) as maxdateof
from t
group by fk;
In other words, your subquery is pretty much all you need.
If you have a reasonable amount of data, you can use a MySQL trick:
select substring_index(group_concat(id order by dateof desc), ',', 1) as id
count(*) as CountOfId, max(dateof) as maxdateof
from t
group by fk;
Note: this is limited by the maximum intermediate size for group_concat(). This parameter can be changed and it is typically large enough for this type of query on a moderately sized table.
You obviously want one result row per fk, so group by it. Then you want the max ID, the row count and the max date for each fk:
select
max(id) as max_id,
count(*) as cnt,
max(date_of) as max_date_of
from tbl
group by fk;

Limit MySQL Results to One From Each "Group"

Suppose we have a table like the one below.
Id | Name | Group
-----------------
1 | John | 1
2 | Zayn | 2
3 | Four | 2
4 | Ben_ | 3
5 | Joe_ | 2
6 | Anna | 1
The query below will select all of them.
SELECT `Name` FROM `Table` WHERE 1;
How would I select only one person from each group? Who it is doesn't really matter, as long as there's only one name from group 1 and one name from group 2 etc.
The GROUP BY clause isn't fit for this (according to my error console) because I am selecting non aggregated values, which makes sense.
The DISTINCT clause isn't great here either, since I don't want to select the "Group" and definitely not group by their names.
If is not important the resulting name You can anawy leverage some group functions eg with max or min..
leverage the group functions
select max(name) from your_table
group by Group;
otherwise you can use subquery
select name from your_table
where Id in (select min(Id) from your_table group by Group);