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.
Related
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;
Actually, i did counted distinct empid rows according to dates. But the problem is i get only one empid record of that specific dates.Please let me know how to get all empid records. Here is my sql query.
$sql = "
SELECT COUNT(DISTINCT subcount.empid) AS CountOf
, subcount.name
, subcount.date
, subcount.empid
, calendar.cdate
FROM subcount
, calendar
WHERE subcount.date = calendar.cdate
GROUP
BY subcount.date
";
Here is sql database.
For example, When you look at 2020-11-10 there are two empid with 10 and 7.
When i tried to get both records i get only empid 10 record or 7 record, though i need both record counts:
Here is the output:
Please help me on this.
I think what you are asking is to get list of employees with count of their submissions on a given date, this could show do it:
SELECT cnt.empid AS EmpId
, sc.Name
, cnt.`date` AS Timestamp
, cnt.CountOf AS SubmissionCount
FROM subcount AS sc
INNER JOIN
(
SELECT subcount.empid
subcount.`date`,
count(*) AS CountOf
FROM subcount
INNER JOIN calendar
ON subcount.`date` = calendar.cdate
GROUP BY
subcount.`date`, subcount.empid
) AS cnt
ON sc.empid == cnt.empid
It uses nested SELECT with GROUP BY to calculate count per employee (empid) and date (not only employee). Outer SELECT join nested SELECT to get subcount.Name piece of data which isn't retrieved in nested SELECT so it needs to be retrieved using outer SELECT.
GROUP BY ___ means result rows per ___. If you group by employee ID, you get one row per employee ID. If you want one row per employee ID and date, group by employee ID and date.
SELECT any_value(s.name), s.`date`, s.empid, c.cdate, count(*)
FROM subcount s
JOIN calendar c on c.cdate = s.`date`
GROUP BY s.`date`, s.empid
ORDER BY s.`date`, s.empid;
I expect a calendar table to have one row per date, so there is exactly one cdate for a result row. The name, however, can be different from row to row, so we must tell the DBMS, which to pick. With ANY_VALUE I tell it that I don't care which.
I'm trying to get the result of the sum of two different tables and find difference of this table: so here are my table
Orders Table
Ship Table
Table and Query
i need to get query result according to item if no quantity then ZERO Tried using ISNULL throws null all values and not result from IFNULL. code or SQL Query Which i have used.
select orders.item,
SUM(orders.quantity) as aQuantity,
SUM(ship.quantity) AS oQuantity,
SUM(orders.quantity) - SUM(ship.quantity) AS diffrence
FROM orders,
ship
GROUP BY orders.item
required Output
Give it a try:
select a.item,IFNULL(o_quant,0) as "o_quant",IFNULL(s_quant,0) as "s_quant",(IFNULL(sum(o_quant),0) - IFNULL(sum(s_quant),0)) as "difference" from (select o.item,sum(o.quantity) "o_quant"
from orders o group by o.item) a left join (select s.item,sum(s.quantity) "s_quant"
from ships s group by s.item) b on a.item = b.item group by a.item,o_quant,s_quant;
I am trying to create an SQL Query to select rows from a database, ordered by a numerical field, however there are repeated entries in the table.
The table consists of the following columns.
UID - Numerical Unique ID
ACCOUNT_NAME - Account Name, unchanged
NICK_NAME - Can be changed by the user at any time
POINTS - Records points held by the user's account
The goal of the query is to display the Account_Name ordered by Points. However, Account_Name is not unique and can appear multiple times in the table.
To deal with this I would like to display only the latest row for each Account_Name.
This meaning that in the results from the select each Account_Name should only appear once. I am trying to have the selection be decided by the UID, meaning that I want only the row with the greatest UID where each account_name appears to be displayed.
I have tried the following without desired results. (The name of the table is ACCOUNT)
SELECT DISTINCT A.account_name , A.uid, A.points
FROM account A, account B
where A.account_name = B.account_name
and A.points > 0
and A.uid >= B.uid
order by A.points DESC;
This doesn't give me the desired results, specifically, there is an account in the database where an outdated row exists with a high value in the Points column. This record appears as the first result in the select, even though it is outdated.
How would you recommend adjusting this Query to select the desired information?
I hope this is enough information to work off of (first time posting a question) Thank you for you help :)
EDIT: Adding in examples with data.
Sample Table Data:
Sample Table Data
Current Results:
Current Results
Desired Results:
Desired Results
Consider joining on an aggregate query calculating MAX(UID)
SELECT a.account_name, a.uid, a.points
FROM account a
INNER JOIN
(
SELECT account_name, MAX(uid) AS max_uid
FROM account
GROUP BY account_name
) agg
ON a.account_name = agg.account_name
AND a.uid = agg.max_uid)
WHERE a.points > 0
ORDER by a.points DESC;
Alternatively, with MySQL 8.0, consider a window function:
SELECT a.account_name, a.uid, a.points
FROM account a
WHERE a.points > 0
AND a.uid = MAX(a.uid) OVER (PARTITION BY a.account_name)
ORDER by a.points DESC;
I am a newbie in MYSQL and had a question regarding the use of MAX and COUNT functions together in MYSQL. I have 2 tables worker and assignment and the primary key of worker is a foreign key in assignment table.
I need to show the employees name and id and the total assignment assigned to him, and only show the person with the most assignment that is the employee with the most assignment.
my code is
SELECT worker.Wrk_ID, worker.Wrk_LastName, MAX(a.count_id)
FROM worker,
(SELECT COUNT(assignment.Wrk_ID) as count_ID
FROM worker, assignment
WHERE worker.Wrk_ID = assignment.Wrk_ID
GROUP BY worker.Wrk_ID)as a
GROUP BY worker.Wrk_ID;
The code is giving an error no. #1054.
Please can anyone help me.
Thanking you in anticipation.
Try something like this:
SELECT worker.Wrk_ID, worker.Wrk_LastName, S.Count
FROM worker
JOIN
(SELECT Wrk_ID, COUNT(*) AS Count FROM Assignments
GROUP BY Wrk_Id ORDER BY COUNT(*) DESC LIMIT 1) S
ON worker.Wrk_ID = S.Wrk_ID
If you want a list of employees sorted by their total assignments:
SELECT w.WrkID, w.Wrk_LastName, COUNT(*) AS Assignments
FROM work w left join Assignments a
ON w.WrkID=a.WrkID
GROUP BY w.WrkID
ORDER BY COUNT(*) DESC;
To allow multiple winners:
SELECT s.*, w.Wrk_Lastname FROM
(
SELECT wrk_id , COUNT(*) AS tot_assignments
FROM Assignments
GROUP BY wrk_id
HAVING COUNT(*) =
(
SELECT MAX(tot) FROM
(
SELECT COUNT(*) AS TOT FROM Assignments GROUP BY wrk_id
) counts
)
) winners
INNER JOIN worker w ON s.wrk_id = w.wrk_id;
It can be slow since it does multiple GROUP BY. Doing it in separated steps in a procedure can be better.