mysql various group by in one query - mysql

I would like to get statistics on my dataset,
for example this is my dataset:
FirstName LastName Country City BirthMonth
Donald Trump England London Jan
Bill Gates England London Sep
Donald Suther England York Sep
Donald Suther Germany Berlin Jan
and this is my 'group_by' list:
[['FirstName', 'LastName'], ['Country', 'City'], ['BirthMonth']]
I would like to get the following statistics:
group by FirstName & LastName:
FirstName LastName Count
Donald Trump 1
Donald Suther 2
Bill Gates 1
group by Country & City:
Country City Count
England London 2
England York 1
Germany Berlin 1
group by BirthMonth:
BirthMonth Count
Jan 2
Sep 2
my query would look like this:
select FirstName, LastName, Country, City, BirthMonth
from my_table
where <some conditions to filter rows only from certain timestamp>
now I have two options:
a. return all values to server and process there (I'm using python) - this query includes many rows and causes overhead
b. query multiple times, each time grouping by the specific fields
select FirstName, LastName, count(*) as group_by
from my_table
where ...
group by FirstName, LastName
c. is there a third option of having one query, and return all different 'group_by's?
and another question:
from (a) and (b) which is better?
I'll note that the group by has limited options - for example 'FirstName' has only 20 options, this means that (b) will result each time less than 20*(num of group by in query rows) < 40, but (a) will result 20^5 rows which is tons of data
to simplify I'll assume there aren't more than 2 columns in a group_by each time,
(which is actually the current situation, it might grow in the future but currently I can use a solution that takes that into account)

You can combine each grouped query with the others using UNION. Fill in the unused columns in each subquery with NULL.
SELECT FirstName, LastName, NULL AS Country, NULL AS City, NULL AS BirthMonth, COUNT(*) AS count
FROM my_table
GROUP BY FirstName, LastName
UNION ALL
SELECT NULL, NULL, Country, City, NULL, COUNT(*)
FROM my_table
GROUP BY Country, City
UNION ALL
SELECT NULL, NULL, NULL, NULL, BirthMonth, COUNT(*)
FROM my_table
GROUP BY BirthMonth

Related

Get id with most records in the table

Table name: Offices
CompanyID OfficeLocation
01 USA
01 Africa
03 USA
04 USA
04 Israel
04 Germany
05 Africa
I need to get CompanyID that have most records in this table (04 for table above)
I tried:
SELECT CompanyID
GROUP BY CompanyID
HAVING COUNT(*) = (
SELECT COUNT (*) FROM EntitySite
GROUP BY CompanyID
ORDER BY COUNT(*) DESC
)
Dsnt work at all(
You can use next simple query:
SELECT CompanyID, COUNT(OfficeLocation) CountOfficeLocation
FROM EntitySite
GROUP BY CompanyID
ORDER BY CountOfficeLocation DESC
LIMIT 1;
MySQL query online
Firstly, question is abstract, data has no obvious relation (different id's have different countries), no know requirement what id is considered when counting (first, last or random).
However, here is query from what I get, this will return most common first and least common last.
SELECT CompanyID
FROM
(
SELECT count(*) as c,
CompanyID
FROM Offices
GROUP BY CompanyID
) T
ORDER BY c desc

Using Distinct, Count and Group together in MySQL

I have a database table of 'attractions' with columns for both the county and/or city for each attraction. I need to display a list of counties and cities together, alphabetically, with the total number of records for each county or city.
The following SQL query works fine except the COUNT is displaying a total of only one for each instead of the total number of attractions in each county or city.
Could anyone tell me how to combine the two SQL statements below together?
SQL:
SELECT entry, COUNT(entry) AS totalForEntry
FROM ( SELECT DISTINCT county AS entry
FROM venues
WHERE (county IS NOT NULL AND county <> '' )
UNION ALL
SELECT DISTINCT city as entry
FROM venues
WHERE (city IS NOT NULL
AND
city <> ''
)
) X GROUP BY entry ORDER BY entry ASC
Results:
Hove (1)
Inverness-shire (1)
Isle of Man (1)
Kent (1)
Lancashire (1)
Leeds (1)
Leicester (1)
Leicestershire (2)
Lincolnshire (1)
Liverpool (1)
The following works for counting the counties, I need it to count the cities too and combine it with the query above:
SELECT DISTINCT county, COUNT(county) AS Count
FROM venues
WHERE (county IS NOT NULL AND county <> '')
GROUP BY county ORDER BY county ASC
The correct result should be something like:
Hove (7)
Inverness-shire (3)
Isle of Man (12)
Kent (20)
Lancashire (34)
Leeds (31)
Leicester (5)
Leicestershire (53)
Lincolnshire (7)
Liverpool (43)
Many thanks in advance.
It doesn't make sense to use DISTINCT with GROUP BY. You can do:
SELECT county AS entry, COUNT(county) AS Count
FROM venues
WHERE (county IS NOT NULL AND county <> '')
GROUP BY county
UNION ALL
SELECT city as entry, COUNT(city) As Count
FROM venues
WHERE (city IS NOT NULL AND city <> '')
GROUP BY city
ORDER BY entry ASC

in MYSQL return Student name with highest score overall

i.e. a table called students (Assume there is only one student with that name, e.g. there isnt two students called John Smith) with
studentName, studentScore, subject
assume table has this
John Smith 40 maths
bob grey 20 english
anne hank 23 english
John Smith 30 english
anne grey 10 maths
I am trying to find the most highest scored student by calculating the maximum of averages of all students
this here will select the highest average but not the student name with that average:
SELECT MAX(avgStudentScore)
FROM (SELECT AVG(studentScore) AS avgStudentScore FROM students GROUP BY studentName) t
thx
If all you need is the name, you can do something like this:
select studentName, avg(studentScore) as avgStudentScore
from students
group by studentName
order by avgStudentScore desc
limit 1
This will return only the first row of the query. Since it's ordered by avgStudentScore, it will return the student with the top average.
The above solution is the simplest and fastests, but it's not the only one. If you want to do it "the hard way" (with subqueries), what you need to do is:
Calculate the average for each student
Get the highest average
Filter the student with the highest average
So... let's do it the hard way ;)
select a.studentName
from
(
select studentName, avg(studentScore) as avgStudentScore
from students
group by studentName
) as a
where
a.avgStudentScore = (
select max(avgStudentScore)
from (
select avg(studentScore) as avgStudentScore
from students
group by studentName
) as a
)
Notice that with this approach the final result might not be unique (i.e. there may be one ore more students with the same average and that average is the highest).
Use this query:
SELECT studentName, max( mark ) as maxMark FROM `student` GROUP BY studentName

Get MAX value based on specific field

Ok, simple question: I have a table
create table people (
id int auto_increment not null primary key,
name varchar(32),
city varchar(32),
age int
);
with the query
SELECT city, age
FROM people
WHERE age=(SELECT max(age) from people);
I can get the output of the city and age of the oldest person.
City Age
Denver 95
How do I get the max age per city, i.e.
City Age
Atlanta 90
Cincinnati 87
Denver 95
SELECT city, MAX(age)
FROM people
GROUP BY city
This is a use of MySQL aggregate functions. By providing an additional column and specifying it in the GROUP BY, you are telling MySQL to only apply the aggregation function (in our case MAX) within those matching records.
You can read more about aggregates here.
Your query can be simplified like
SELECT city, age
FROM people
order by age desc
limit 1

How can I select the first time a number shows up in more than one column in MySQL?

I have a table of flights, which have an origin and destination city, represented as a foreign id.
A very simplified example of this table looks like:
id | origin | destination
023 1 3
044 3 2
332 2 1
509 1 3
493 1 4
I need to get the first time that a city shows up as an origin or a destination; a list of all the flights that contain a city that hasn't been flown to or from yet.
What I would like to get for the above example would be:
023: 1, 3
044: 2
493: 4
Flights 332 and 509 aren't in the output because they only visit cities that have already been visited.
Here's what I've tried:
(SELECT distinct(origin), distinct(destination) FROM flights ORDER BY id)
Doesn't work because you can't select more than one distinct column
SELECT (distinct(origin) FROM flights ORDER BY id) UNION (distinct (destination) FROM flights ORDER BY id)
Doesn't work because of syntax errors, but mainly because it doesn't take into account that a city should be unique in the origin and destination columns.
If there's not a quick way to do this in SQL I'm also happy to just iterate through and keep track of cities that have been visited (this app has literally one user, and he doesn't care about a few milliseconds of computation because he's over 80), but I'd love to know just so that I can learn more about SQL!
This does it:
SELECT id, GROUP_CONCAT(city ORDER BY city) cities
FROM (
SELECT city, min(id) id
FROM (
SELECT origin city, MIN(id) id
FROM flights
GROUP BY city
UNION
SELECT destination city, MIN(id) id
FROM flights
GROUP BY city) u
GROUP BY city) x
GROUP BY id
DEMO