Query: Count Alphabetical wise name - mysql

I have one voter table which contain large amount of data. Like
Voter_id name age
1 san 24
2 dnyani 20
3 pavan 23
4 ddanial 19
5 sam 20
6 pickso 38
I need to show all voter_name by Alphabetically and count them.Like
name
san
sam
s...
s...
dnyani
ddanial
d...
pavan
pickso
p..
p..
I try using count(voter_name) or GROUP BY.
But both not working for me..... Suppose table contain 50 voters details.
number of person name start with A=15,b=2, c=10,y=3 and so on.
Then how to count and show first 15 record of 'A' person, next 2 record of 'B' person and so on..
Give me any reference or hint..
Thanks in Advance.

It is as simple as this,
SELECT SUBSTRING(name,1,1) as ALPHABET, COUNT(name) as COUNT
FROM voter GROUP BY SUBSTRING(name,1,1);

This order names only:
SELECT `name` FROM `voter` ORDER BY `name` ASC
This counts each occurrence of the first letter and group them group them together
ex.:
Letter COUNT
------ -------
A 15
B 2
C 10
y 3
SELECT SUBSTR(`name`,1,1) GRP, COUNT(`name`) FROM `voter` WHERE
SUBSTR(`name`,1,1)=SUBSTR(`name`,1,1) GROUP BY GRP ORDER BY GRP ASC
Here you go!

If you need names and their counts in ascending order, then you can use:
SELECT
name, COUNT(*) AS name_count
FROM
voter
GROUP BY
name
ORDER BY
name ASC
Which will give the output like
name name_count
------------------
albert 15
baby 6
...
If you need to display all records along with their counts, then you may use this:
SELECT
voter_id, name, age, name_count
FROM
(
SELECT
name, COUNT(name) AS name_count
FROM
voter
GROUP BY
name
) counts
JOIN actor
USING (name)
ORDER BY
name
and you get the output as:
voter_id name age name_count
------------------------------------
6 abraham 26 2
24 abraham 36 2
2 albert 19 1
4 babu 24 4
15 babu 53 4
99 babu 28 4
76 babu 43 4
...

Check the SUBSTRING function of MySQL here
http://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_substring
And we can use a sub-query to achieve our result.
So using that, how about this
SELECT voter_id, name, age, COUNT(*) AS alphabet
FROM
(SELECT voter_id, name, age, SUBSTRING(name, 1, 1) AS first_letter FROM voter)
AS voter
GROUP BY first_letter
ORDER BY first_letter ASC

Related

How to select one column with all distinct values based on some clause

I essentially like to have one query which I'll execute one time and like to have the result (no multiple query execution) and definitely, the query should use simple MySQL structure (no complex/advanced structure to be used like BEGIN, loop, cursor).
Say I've two tables.
1st Table = Country (id(PK), name);
2nd Table = Businessman (id(PK), name, city, country_id(FK))
Like to SELECT all countries, whose businessmen are from distinct cities. No two businessmen exist in one country, who are from the same city. If so, that country will not be selected by the SELECT clause.
Country
id name
1 India
2 China
3 Bahrain
4 Finland
5 Germany
6 France
Businessman
id name city country_id
1 BM1 Kolkata 1
2 BM2 Delhi 1
3 BM3 Mumbai 1
4 BM4 Beijing 2
5 BM5 Paris 6
6 BM6 Beijing 2
7 BM7 Forssa 4
8 BM8 Anqing 2
9 BM9 Berlin 5
10 BM10 Riffa 3
11 BM11 Nice 6
12 BM12 Helsinki 4
13 BM13 Bremen 5
14 BM14 Wiesbaden 5
15 BM15 Angers 6
16 BM16 Sitra  3
17 BM17 Adliya 3
18 BM18 Caen 6
19 BM19 Jinjiang 2
20 BM20 Tubli 3
21 BM21 Duisburg 5
22 BM22 Helsinki 4
23 BM23 Kaarina 4
24 BM24 Bonn 5
25 BM25 Kemi 4
In this respect, China and Finland shouldn't be listed.
I've attempted using count and group by, but no luck.
Can you please help me to build up this query.
Here it is, all you need is to join Businessman table and count cities and distinct cities and if they equal that means all businessmen are from different cities:
SELECT
c.`id`,
c.`name`,
COUNT(b.`id`) AS BusinessmanCount,
COUNT(b.`city`) AS CityCount,
COUNT(DISTINCT b.`city`) AS DistinctCityCount
FROM `countries` c
INNER JOIN Businessman b ON c.`id` = b.`country_id`
GROUP BY c.`id`
HAVING CityCount = DistinctCityCount
For minified version what you exactly need:
SELECT
c.`id`,
c.`name`
FROM `countries` c
INNER JOIN Businessman b ON c.`id` = b.`country_id`
GROUP BY c.`id`
HAVING COUNT(b.`city`) = COUNT(DISTINCT b.`city`)
Well, I think we should have waited for you to show your own query, because one learns best from mistakes and their explanations. However, now that you've got answers already:
Yes, you need group by and count. I'd group by cities to see if I got duplicates. Then select countries and exclude those that have duplicate cities.
select *
from country
where id not in
(
select country_id
from businessmen
group by city, country_id
having count(*) > 1
);
You need either nested aggregations:
select *
from Country
where id in
(
select country_id
from
(
select city, country_id,
count(*) as cnt -- get the number of rows per country/city
from Businessman
group by city, country_id
) as dt
group by country_id
having max(cnt) = 1 -- return only those countries where all counts are unique
)
Or compare two counts:
select *
from Country
where id in
(
select country_id
from Businessman
group by country_id
having count(*) = count(distinct city) -- number of cities is equal to umber of rows
)

How to get value and count if it appears next 3 consecutive times

I have table with 3 columns, now how find value if it appears next 3 times immediately
i.e 1st trnas_value appears in next 3 consecutive times (repeaded 4 times)
and 2nd and 6th also rows also repeated the same
date tran_val name
23mar 22 mark
24mar 22 mark
25mar 22 mark
26mar 22 mark
27mar 22 mark
28jan 99 john
29jan 99 john
30jan 99 john
31jan 99 john
output
name trans_value consecutive_count
mark 22 2
john 99 1
Basic way to do it is to add a sequence number, ordering by the field that contains the relevant order.
I am not sure about the counts, but the easiest way seems to be to just subtract 3 from the consecutive count.
SELECT name,
tran_val,
MAX(cnt - 3) AS consecutive_count
FROM
(
SELECT date,
tran_val,
name,
#cnt:=IF(#tran_val=tran_val AND #name=name, #cnt + 1, 1) AS cnt,
#tran_val:=tran_val,
#name:=name
FROM some_table
CROSS JOIN (SELECT #cnt:=0, #tran_val:=0, #name:='') sub0
ORDER BY `date`
) sub1
GROUP BY name,
tran_val

mysql count items in group_concat

I am having a trouble with using GROUP_CONCAT in MySQL
My tables g0 as follows:
ID Age Sex
-------------
1 16 Male
2 18 Female
3 16 Male
4 18 Female
5 16 Male
But I need the table to look like
ID count
1,3,5 3
2,4 2
I tried this query:
SELECT GROUP_CONCAT(
CONCAT(cnt)) cnts FROM
(SELECT COUNT(ID) as cnt FROM g0 GROUP BY Age , Sex order by ID Desc) ;
But I get this error message:
1248. Every derived table must have it's own alias
There's no need to have the count inside group_concat - just select it as a different item with the same group by expression:
SELECT GROUP_CONCAT(id), COUNT(*)
FROM g0
GROUP BY age, sex
ORDER BY 1 DESC

Sort the SQL table by name using maximum of quantity

I have an SQL selection which return the following:
Name Code Qty
Janet 10 6
Janet 11 9
Janet 09 8
Jones 12 7
Jones 11 8
James 09 5
James 10 4
I want this selection to get sorted based on the qty for all the three people : order the people by their maximum quantity, and then order by quantity.
The output should look like this:
Janet 11 9
Janet 09 8
Janet 10 6
Jones 11 8
Jones 12 7
James 09 5
James 10 4
Any way to achieve this?
This is a subtle problem. It looks like you want to sort the names by the maximum of qty. This requires a join and aggregation to get the maximum qty for each name:
select t.*
from table t join
(select name, max(qty) as maxq
from table t
group by name
) tt
order by tt.maxq desc, tt.name, t.qty desc;
Try this:
SELECT * FROM `names` ORDER BY name ASC, qty DESC
SELECT Name, Code, Qty
FROM names AS main JOIN
(SELECT Name, MAX(Qty) AS max_qty
FROM names
GROUP BY Name) AS max_names USING (Name)
ORDER BY max_names.max_qty DESC, names.Qty DESC
The virtual table max_names contains the maximal Qty for each Name:
Janet 9
Jones 8
James 5
Then you join it to the original table and sort according to this max_qty.
If you want to sort according to the total quantity per name, just replace MAX with SUM:
SELECT Name, Code, Qty
FROM names AS main JOIN
(SELECT Name, SUM(Qty) AS sum_qty
FROM names
GROUP BY Name) AS sum_names USING (Name)
ORDER BY sum_names.sum_qty DESC, names.Qty DESC
The sum_names table will contain:
Janet 23
Jones 15
James 9
You can specify more than one sorting condition:
SELECT * from names order by name, qty desc
Above query will sort by name and if names are equal then will sort by qty
If you want to select only higher qty for every user then use this query:
SELECT name, MAX(qty) FROM names GROUP BY name order by MAX(qty);

Select a value where another column has the highest value

I have a table with people, their age, and their awesomeness at each age.
What is the simplest query to get John's 'awesomeness' at their maximum age?
People
Name Age Awesomeness
Don 1 12
Don 2 23
Don 3 43
Don 4 30
Sam 1 9
Sam 2 18
Sam 3 59
Sam 4 99
The best query I have:
SELECT awesomeness
FROM people
JOIN (
SELECT MAX(age)
FROM people
WHERE name = 'Don'
) a
ON people.age = a.age
WHERE people.name = 'Don'
Just use order by and limit:
SELECT awesomeness
FROM people
WHERE people.name = 'Don'
ORDER BY age desc
LIMIT 1
You may be wishing to show everyone's score at their maximum age.
You can do that with this query: http://sqlfiddle.com/#!2/b0ff4/1/0
SELECT a.name, a.awesomeness
FROM people a
JOIN (
SELECT name, MAX(age) age
FROM people
GROUP by name
) b ON a.name = b.name AND a.age=b.age