How to select max value and max value count by group - mysql

I have a table in which i have to calculate max value and count of (calculate max value) group by name and sex.
sample input:
name sex age
A F 2
A F 3
A M 4
B F 6
B M 7
B M 7
B F 4
C M 8
C M 8
C M 8
C M 3
C F 1
C F 10
C F 10
Sample Output:
name sex max_age count_max_age
A F 3 1
A M 4 1
B F 6 1
B M 7 2
C F 10 2
C M 8 3
I have tried
select name,sex,max(age) as max_age , count(max_age) from table_1 group by name ,sex
I am getting an error
Unknown column max_age in fieldlist
please suggest any modifications required in above query.
Thanks in advance

SELECT count(max_age), name, sex FROM (
SELECT name, sex, max(age) as max_age from table_1 group by name, sex
) as max_age_group group by name, sex
query will not understand the alias on the same level, however you can make it as a subquery.

Use a subquery and join like below
select
t1.name, t1.sex, max_age, count(max_age) as countofmaxage
from
(select name, sex, max(age) as max_age
from t
group by name, sex) t1
join
t on t1.name = t.name and t1.sex = t.sex and t1.max_age = t.age
group by
t1.name, t1.sex, max_age
Output:
name sex max_age countofmaxage
----------------------------------
A F 3 1
A M 4 1
B F 6 1
B M 7 2
C F 10 2
C M 8 3
DEMO in fiddle

Related

Remove the line with the same name but different value

So basically I run this code in sql:
SELECT p.Nome as Nome_pub, a.Nome as Nome_area, COUNT(*) as total
FROM publicacao p, emprestimo e, area_tematica a
WHERE p.Id=e.Publicacao_Id and p.Area_Tematica_Id=a.Id and (Data_hora>='2021-01-01' AND Data_de_devolucao<='2021-06-31')
GROUP by p.Nome
ORDER BY Nome_area;
and I get the following output
Nome_pub
Nome_area
total
name1
a
1
name2
b
1
name3
c
1
name4
d
3
name5
d
2
name6
d
2
name7
e
1
but I want an output that gives me the max word3 based on word2 basically: (in my case remove line with "name5" and "name6"
Nome_pub
Nome_area
total
name1
a
1
name2
b
1
name3
c
1
name4
d
3
name7
e
1
is there any way to do this??
Thanks in advance!!
If ROW_NUMBER is available in your version.
SELECT Nome_pub, Nome_area, total
(
SELECT
p.Nome as Nome_pub
, a.Nome as Nome_area
, COUNT(*) as total
, ROW_NUMBER() OVER (PARTITION BY a.Nome ORDER BY COUNT(*) DESC) as RN
FROM publicacao p
JOIN emprestimo e
ON p.Id = e.Publicacao_Id
JOIN area_tematica a
ON a.Id = p.Area_Tematica_Id
WHERE ( Data_hora >= DATE '2021-01-01' AND
Data_de_devolucao < DATE '2021-07-01')
GROUP by p.Nome, a.Nome
) q
WHERE RN = 1
ORDER BY Nome_area;

MySQL GROUP_CONCAT excluding group value

I am trying to do a group concat for the table below
l r num
A B 1
A C 3
A A 5
B C 5
B C 7
B C 9
C A 1
C A 2
C C 3
I would like get the group concat of those elements which do not belong to the group when we use GROUP BY and also sum the numbers (in a similar way). For example, the output I am trying to obtain is
l grps sum(num)
A B,C 4
B C 21
C A 3
I am currently getting the output as below
l grps sum(num)
A B,C,A 9
B C 21
C A,C 6
I use the query below
SELECT l, group_concat(distinct r), sum(num)
from groups
group by l;
The SQL fiddle is here
SELECT l, GROUP_CONCAT(DISTINCT r), SUM(num)
FROM groups
WHERE l <> r
GROUP BY l;

SQL Number of Occurrences, summary Query

I have a table as below,
Product Promotion exists (Y/N) Week
A Y 1
B Y 1
C Y 1
A Y 2
B Y 2
C N 2
A Y 3
B Y 3
C Y 3
A Y 4
B Y 4
C N 4
I want to see an Promition exists combination Output on total table. Something like
A, B - 4
B,C - 2
A,C - 2
Since this is Just for 3 products looks simple.. I am looking at some thousands of records, and looking for same combinations where total count of occurrence is greater than some number. If taking the above example, if that count is 4.. then my output should be
A,B - 4
Try this:
SELECT p1, p2, COUNT(*) AS cnt
FROM (
SELECT t1.Product AS p1, t2.Product AS p2
FROM mytable AS t1
JOIN mytable AS t2
ON t1.Week = t2.Week AND
t1.Product < t2.Product AND
t1.Exists = 'Y' AND t2.Exists = 'Y') AS t
GROUP BY p1, p2
ORDER BY cnt DESC
To get only pairs exceeding a certain value, just wrap the above in a subquery and add a WHERE cnt >= someValue.
Demo here

MYSQL get the first value in JOIN query

I have 3 tables: A, B and C.
A has AID, B has AID and BID, and C has BID Value and Date.
I need to create a query that returns me AID and the first (according to date) Value from C.
WHAT I've tried:
SELECT A.AID, Value FROM A INNER JOIN B on A.AID = B.BID
INNER JOIN C ON C.BID = B.BID GROUP BY A.AID
It gives me the last Value and not the first.
Data example:
A:
AID:
1
2
3
B:
AID BID
1 1
1 2
2 3
3 4
3 5
3 6
C:
BID Value Date
1 15 1.1.1970
1 422 1.1.1992
2 945 1.1.1975
3 149 1.1.1994
3 147 1.1.2015
4 110 1.1.2004
5 142 1.1.2005
The output should be:
AID Value
1 15
2 149
3 110
If you do not have too many records with the same value and value doesn't have any commas, then the group_concat()/substring_index() trick is probably the easiest way:
select b.aid,
substring_index(group_concat(c.value order by c.date desc), ',' 1) as first_value
from c join
b
on c.bid = b.bid
group by b.aid;
Larger amounts of data require a more complicated query. Something like:
select b.aid, c.value
from c join
b
on c.bid = b.bid
where c.date = (select min(c2.date)
from c2 join
b2
on c2.bid = b2.bid
where b2.aid = b.aid
);
To restrict C to just those rows with the latest (minimum) date you need a subquery that will produce the minimum date, then use that to limit the rows from C
SELECT
A.AID
, C.Value
FROM A
INNER JOIN B ON A.AID = B.BID
INNER JOIN C ON b.bid = c.bid
INNER JOIN (
SELECT
bid
, MIN(date) AS mindate
FROM c
GROUP BY
bid
) AS m ON c.bid = m.bid
AND c.date = m.mindate
DROP TABLE IF EXISTS b;
CREATE TABLE b
(aid INT NOT NULL
,bid INT NOT NULL
,PRIMARY KEY(aid,bid)
);
INSERT INTO b VALUES
(1 ,1),
(1 ,2),
(2 ,3),
(3 ,4),
(3 ,5),
(3 ,6);
DROP TABLE IF EXISTS c;
CREATE TABLE c
(bid INT NOT NULL
,value INT NOT NULL
,date DATE
,PRIMARY KEY(bid,date)
);
INSERT INTO c VALUES
(1 ,15 ,'1970-01-01'),
(1 ,422 ,'1992-01-01'),
(2 ,945 ,'1975-01-01'),
(3 ,149 ,'1994-01-01'),
(3 ,147 ,'2015-01-01'),
(4 ,110 ,'2004-01-01'),
(5 ,142 ,'2005-01-01');
SELECT x.aid
, y.value
FROM b x
JOIN c y
ON y.bid = x.bid
JOIN
( SELECT b.aid
, MIN(c.date) min_date
FROM b
JOIN c
ON c.bid = b.bid
GROUP
BY b.aid
) z
ON z.min_date = y.date
AND z.aid = x.aid;
+-----+-------+
| aid | value |
+-----+-------+
| 1 | 15 |
| 2 | 149 |
| 3 | 110 |
+-----+-------+

SQL COUNT & GROUP BY

I have this table
---ID----NAME----INVITED_BY---
1 A
2 B 1
3 C 1
4 D 2
all I want is to get the result:
---ID----NAME------INVITES---------
1 A 2 (COUNT OF INVITED_BY)
2 B 1
3 C 0
4 D 0
You could do a self join to count the number of persons invited:
select yt.id
, yt.name
, count(distinct inv_by.id) as invites
from YourTable yt
left join
YourTable inv_by
on yt.id = inv_by.invited_by
group by
yt.id
, yt.name