Fetch who voted and how many votes were given to each country - mysql

I need help with query how to fetch who voted and how many votes were given to each country using MySQL?
So, I have table voter and result, you can find the dummy dataset here https://github.com/FirzaCank/Project/blob/main/SQL/Self%20Project/Vote%20Poll/Dataset%20Dummy%20voter.sql
Which voter table contains:
ID (INT)
first_name VARCHAR(10)
last_name VARCHAR(10)
and result table contains:
voter_id (INT)
country VARCHAR(10)
I've tried a MySQL query like this:
SELECT
country,
CONCAT(v.first_name,' ',v.last_name,' x ',COUNT(r.voter_id)) AS votes
FROM voter v
RIGHT JOIN result r ON v.id = r.voter_id
GROUP BY country;
But I got an error, I'm sure this problem need something like loops but I don't really understand that stuff.
The desired output is will be like this, but as far as I've tried in the above syntax it just came out with my output which I can't display all voter in the same country, I just came out with 1 voter every 1 country.

SELECT
country,
group_concat(votes,',') as votes
FROM
(
SELECT
country,
CONCAT(v.first_name,' ',v.last_name,' x ',COUNT(r.voter_id)) AS votes
FROM voter v
RIGHT JOIN result r ON v.id = r.voter_id
GROUP BY country,first_name,last_name
) x
GROUP BY country;
see: DBFIDDLE
First your query give an error. This one:
"SELECT list is not in GROUP BY clause and contains nonaggregated
column '...first_name' which is not functionally
dependent on columns in GROUP BY clause; this is incompatible with
sql_mode=only_full_group_by"
This error, and how to handle it, is epxlained here: MySQL Handling of GROUP BY
This means that all fields that are not used in an aggregate function, you be mentioned in the GROUP BY.
Because your desire is that the output only contains 1 line per country the GROUP_CONCAT function is added on the result.

Another way, (probably a bit more optimal on big data, because aggregation happens over single table):
select country, group_concat(concat(first_name, ' ', last_name, ' x ', c) order by c desc)
from (
select country, voter_id, count(*) c
from result
group by country, voter_id
) x
join voter on id = voter_id
group by country;

Related

Using JOIN in sql for two derived tables

Basically, I have two separate queries, which I need to somehow merge into one set of results.
![This is Table 1, which shows the sum of each group's salary]
1
Here is the queries I wrote to form the tables.
SELECT con_stagename, SUM(p_daily_salary) AS sum_salary
FROM CONTENDER, PARTICIPANT
WHERE p_contender = con_id
GROUP BY con_id;
SELECT MAX(sum_salary) AS max_salary
FROM (SELECT con_stagename, SUM(p_daily_salary) AS sum_salary
FROM CONTENDER, PARTICIPANT
WHERE p_contender = con_id
GROUP BY con_id) T2;
And the question is, if I want the result to be a single row of values, which the name of the group with the highest salary, and the actual amount. How would I do it? I've been trying to use JOIN operations but there was not luck.
SELECT con_stagename, SUM(p_daily_salary) AS sum_salary
FROM CONTENDER, PARTICIPANT
WHERE p_contender = con_id
GROUP BY con_id
ORDER BY 2 DESC
LIMIT 1

SQL Query to get country_name and count of occurances when another column is like

I have 2 MySQL tables , one called trials and has columns
nct_id,
off_title,
brief_title
and the other one that is called countries and has columns
nct_id
country_name
I want to write an sql query that finds :
the countries and number of occurancies (with count) when off_title or brief_title is like a specific input.
I have tried this query but it doesn't seem to work:
SELECT country_name , count(country_name) as cnt
FROM trials,countries
WHERE off_title LIKE "%something%" or brief_title LIKE "%something%"
GROUP BY country_name
ORDER BY cnt ASC
SELECT country_name, count(*)
FROM countries c JOIN trials t on c.nct_id = t.nct_id
WHERE off_title LIKE "%something%" or brief_title LIKE "%something%"
GROUP BY country_name
Try to join tables together first.

SQL: What country has the most cities?

Hello I started using MySQL and I seem to be having trouble trying to nest formulas. I'm working on a problem and the question is, What country has the most cities?
I have two tables:
CITY:
city
city_id
country_id
COUNTRY:
country
country_id
I am able to join the two tables together to get the cities to match with the countries but after that I don't know how to count to the country that has the most cities.
My current code is:
SELECT city.city, country.country
FROM city, country
WHERE city.country_id = country.country_id
From there I don't know how to add a count function without it coming back as as error. I dont fully understand the basics of nesting.
Thank you, any help is appreciated.
You do not need to do nesting necessarily. To simply know, which country has most number of cities, just use group by:
select country_id, count(1)
from city
group by country_id
This will give you the number of cities in each country. Then you could use a CTE to get the country with the largest number of cities.
You need to GROUP BY if you want to use aggregate functions.
Given the fact that you're very new to this I think you'll get a lot more out of this if you spend a few minutes reading up on some documentation. Don't worry, this is easy stuff so you'll understand this in no time. Please have a look at the following basic info (MySQL GROUP BY basic info) regarding the use of GROUP BY in MySQL. Your questions are answered in the topic regarding 'MySQL GROUP BY with aggregate functions'.
Basic group by:
SELECT
status, COUNT(*)
FROM
orders
GROUP BY status;
Group by using a join:
SELECT
status, SUM(quantityOrdered * priceEach) AS amount
FROM
orders
INNER JOIN
orderdetails USING (orderNumber)
GROUP BY status;
SELECT x.country
FROM country x
JOIN city y
ON y.country_id = x.country_id
GROUP
BY x.country
ORDER
BY COUNT(*) DESC LIMIT 1;
On the (fantastically unlikely) chance that the most civilised countries have equal numbers of cities, you would have to amend this a little.
What makes this difficult is possible ties, i.e. two or more countries sharing the maximum number of cities. As of MySQL 8 you can use window functions to help you with this. Here I compare the country counts and their maximum and then pick the rows were the two match.
select *
from country
where (country_id, true) in -- true means it is a maximum city country
(
select country_id, count(*) = max(count(*)) over()
from city
group by country_id
);
Sorry it was my first post, my code looks terrible.
following my code again.
select
country.country_id,
count(city.city_id)
from
country
inner join
city
on
city.country_id=country.country_id
group by
city.country_id
having
count(city.city_id) =
(SELECT
max(count(city.city_id))
FROM
city
GROUP BY
city.city_id);
Best regards,
Jens
Try the following code:
**select
country.country_id,
count(city.city_id)
from
country
inner join
city
on
city.country_id=country.country_id
group by
city.country_id
having
count(city.city_id) =
(SELECT
max(count(city.city_id))
FROM
city
GROUP BY
city.city_id);**
You need to group by country_id to make sure all cities that are connected to one country_id can be counted.
Where is a good approach, however it does not work together with "group by" as it will be accounted before the "group by" command.
The way you joined your data from different tables is not a very proper yet working way. I suggest to use the inner join in this case to make the command more obvious/better readable.
Count() is used to count the number of cities that accumulate on one country
max() is used to get the country with the most cities (highest count()).
SELECT country_id, count(1)
FROM city
GROUP BY country_id
ORDER BY count(1) desc;
Try following Code -
SELECT *,
(SELECT COUNT(*) FROM cities WHERE cities.country_id=C.country_id) as cities_count
FROM country C
ORDER BY cities_count DESC
LIMIT 0,1
Also is joining the two tables necessary? In your query, you said you need to find What country has the most cities?
Above query will only return one country with max cities.
You can find the country like this:
SELECT MAX(c.id) FROM (SELECT COUNT(id) AS id
FROM city group by country_id) c

SQL on MIN COUNT error code 1248

In MySQL database, I have a table named 'customer'. The task is to list the names of states with the least number of customers without displaying states with no (zero) customers.
Here is my command:
SELECT MIN(mycount)
(SELECT
state,COUNT(customerNumber) mycount
FROM customers
WHERE state IS NOT NULL
GROUP BY customers.state
HAVING COUNT(customerNumber) > 0);
But it gives an error of #1248 - Every derived table must have its own alias
You were missing a from clause. Also, as the error says, you have to specify an alias for the derived table (t as shown below). It can be anything else as well).
SELECT MIN(mycount)
from
(SELECT state,COUNT(customerNumber) mycount
FROM customers
WHERE state IS NOT NULL
GROUP BY customers.state
HAVING COUNT(customerNumber) > 0) t --table alias
If you want the states with the fewest customers, then the query should look like this
select state
from customers
group by state
having count(*) = (select min(cnt)
from (select count(*) from customers group by state) s
);
You can add count(*) to the outer select if you want the count as well.

sql query or subquery

So i have a table called cities with the attribute path (can have duplicate or more equal entries), name and kms, and i need to filter it so that i have entries with only one entry of each for path with the highest kms. what i have now is
SELECT cities.*
FROM cities, categories
group by cities.path , cities.kms
ORDER BY cities.kms desc
the problem is that it gives me back duplicated entries for path( wich i dont want) and also it doesnt order it by kms like i want. What should i do?
I see no purpose for the categories table in your query, so I have eliminated it in my answer.
SELECT c1.path, c1.name, c1.kms
FROM cities c1
INNER JOIN (SELECT c2.path, MAX(c2.kms) AS Maxkms
FROM cities c2
GROUP BY c2.path) q
ON c1.path = q.path
AND c1.kms = q.Maxkms
GROUP BY path only with MAX(kms):
SELECT cities.path, MAX(cities.kms)
FROM cities
GROUP BY cities.path
ORDER BY cities.kms desc
ORDER BY should order by kms, unless it is not of type numeric may be string. Ensure its type.