There is a table:
ID City
1 Toronto
2 Toronto
3 Toronto
4 Toronto
5 NY
6 NY
How to get the following table:
City Total
NULL 6
Toronto 4
NY 2
I plan to use union:
(select city, count(*) as total from tbl group by city)
union
(select null, count(*) as total from tbl)
Is it possible to use something like to reuse the subquery:
(select city, count(*) as total from tbl group by city) tmp
union
(select null, count(*) as tmp from tbl)
Or sql already optimizes
(select city, count(*) as total from tbl group by city)
union
(select null, count(*) as total from tbl)
?
In at least MySQL 5.5 and newer, you can use the WITH ROLLUP modifier to get a total sum of the grouped elements without an extra query;
SELECT city, COUNT(*) AS total FROM tbl GROUP BY city WITH ROLLUP
city total
---------------
NY 2
Toronto 4
(null) 6
An SQLfiddle to test with.
You can't reuse the the query but you could use a view for reuse the code
create view my_view as
select city, count(*) as total
from tbl group by city
once created the view you could
select city, total
from my_view
union
select null, sum(total)
from my_view
1) Take aliases are only visible to join members and subquery. Not to union members.
2) The query as you wrote it makes little sense: aliasing tmp to a table then a scalar?
To achieve what you want to achieve, you can try using CTEs:
WITH tmp AS (SELECT city, COUNT(*) AS cnt GROUP BY city)
SELECT * FROM tmp UNION SELECT null, SUM(cnt) FROM tmp
I don't know what the performance difference would be. If you have an index on city, I doubt you will see a difference.
You use WITH ROLLUP in a subquery and then arrange the ordering in the outer query to put the rollup record on top:
SELECT *
FROM (SELECT city, COUNT(*) AS total FROM mytable GROUP BY city WITH ROLLUP) x
ORDER BY
CASE WHEN city IS NULL THEN 0 ELSE 1 END,
city
If you are planning to order the results by descending total, that's even simpler:
SELECT *
FROM (SELECT city, COUNT(*) AS total FROM mytable GROUP BY city WITH ROLLUP) x
ORDER BY total DESC
Demo on DB Fiddlde:
| city | total |
| ------- | ----- |
| | 6 |
| Toronto | 4 |
| NY | 2 |
Related
Here I have this table:
Copies
nInv | Subject | LoanDate | BookCode |MemberCode|
1 |Storia |15/04/2019 00:00:00 |7844455544| 1 |
2 |Geografia |12/09/2020 00:00:00 |8004554785| 4 |
4 |Francese |17/05/2006 00:00:00 |8004894886| 3 |
5 |Matematica |17/06/2014 00:00:00 |8004575185| 3 |
I'm trying to find the value of the highest number of duplicates in the MemberCode column. So in this case I should get 3 as result, as its value appears two times in the table. Also, MemberCode is PK in another table, so ideally I should select all rows of the second table that match the MemberCode in both tables. For the second part I guess I should write something like SELECT * FROM Table2, Copies WHERE Copies.MemberCode = Table2.MemberCode but I'm missing out almost everything on the first part. Can you guys help me?
Use group by and limit:
select membercode, count(*) as num
from t
group by membercode
order by count(*) desc
limit 1;
SELECT MAX(counted) FROM
(SELECT COUNT(MemberCode) AS counted
FROM table_name GROUP BY MemberCode)
Using analytic functions, we can assign a rank to each member code based on its count. Then, we can figure out what its count is.
WITH cte AS (
SELECT t2.MemberCode, COUNT(*) AS cnt,
RANK() OVER (ORDER BY COUNT(*) DESC, t2.MemberCode) rnk
FROM Table2 t2
INNER JOIN Copies c ON c.MemberCode = t2.MemberCode
GROUP BY t2.MemberCode
)
SELECT cnt
FROM cte
WHERE rnk = 1;
Something like this
with top_dupe_member_cte as (
select top(1) MemberCode, Count(*)
from MemberTable
group by MemberCode
order by 2 desc)
select /* columns from your other table */
from OtherTable ot
join top_dupe_member_cte dmc on ot.MemberCode=dmc.MemberCode;
I have student table
id | name | zip
1 | abc | 1234
2 | xyz | 4321
3 | cde | 1234
And i want to only display unique zip code which is 4321. I don't want to display the 1 and 3 record number. So, how can i display the unique record only?
Thanks In Advance.
The following query will give you all zip codes which don't appear in duplicate:
SELECT zip
FROM yourTable
GROUP BY zip
HAVING COUNT(*) = 1
If you want to also get the full records then you can use the above as a subquery to filter the original table:
SELECT *
FROM yourTable t1
INNER JOIN
(
SELECT zip
FROM yourTable
GROUP BY zip
HAVING COUNT(*) = 1
) t2
ON t1.zip = t2.zip
or this:
SELECT *
FROM yourTable
WHERE zip IN
(
SELECT zip
FROM yourTable
GROUP BY zip
HAVING COUNT(*) = 1
)
This will also work
select
id, name, zip
from
(select
id, name, zip, count(zip) as countZip
from
student
group by zip) as subq
where
countZip = '1'
There is a DISTINCT modifier that forces a select to show only one value for a column that may appear several times. In your case it would be:
SELECT DISTINCT ZIP
FROM ...
I have a table with two columns - region and profession
region | profession
India | IT
India | IT
US | HR
US | HR
India | HR
I want to display the most popular profession in every region. the output should only be
Region | Profession
India | IT
US | HR
First, get a count of the results per group. Then you need to establish an order per group -- mysql can do this with user-defined variables.
Here's an example:
select region, profession
from (
select region, profession,
#rn:=if(#oldregion=region,#rn+1,0) rn,
#oldregion:=region
from (
select region, profession, count(*) cnt
from yourtable
group by region, profession) t, (select #rn:=0, #oldregion='') t2
order by region, cnt desc) t3
where rn = 0
SQL Fiddle Demo
Here's another solution using a correlated subquery:
select distinct region, (
select profession
from yourtable t2
where t.region = t2.region
group by region, profession
order by count(*) desc
limit 1) as profession
from yourtable t
More Fiddle
I have table with this data :
1. John | seafood pizza
2. Mike | pepperoni pizza
3. Mike | pepperoni pizza
4. John | original pizza
5. Mike | original pizza
6. John | seafood pizza
7. John | pepperoni pizza
....
How can I write a query that give me result such this:
John | seafood pizza
Mike | pepperoni pizza
If client have same quantity for many pizzas, the result may be any pizza's name.
Let's take it step by step
the following query will give you number of times each client ordered each kind of pizza
SELECT name, pizza, COUNT(*) AS cnt
FROM yourTable
GROUP BY name, pizza
So how do we get the most often ordered pizza from that? We must first know, what is the highest number of pizza ordered by each client
SELECT name, MAX(cnt) AS cnt FROM (
SELECT name, pizza, COUNT(*) AS cnt
FROM yourTable
GROUP BY name, pizza
) AS subquery GROUP BY name
then use this number to select actual pizza name
SELECT name, pizza, COUNT(*) AS cnt
FROM yourTable AS t
CROSS JOIN (
SELECT name, MAX(cnt) AS cnt FROM (
SELECT name, pizza, COUNT(*) AS cnt
FROM yourTable
GROUP BY name, pizza
) AS subquery GROUP BY name
) AS sq
USING(name,cnt)
GROUP BY name, pizza
I'd go with grouping the counts by user and pizza then using this as a datasource for a query which finds the groupwise maximum (using the max concat trick). It's not hard:
SELECT user, SUBSTRING(MAX(CONCAT(LPAD(freq, 6, '0'),pizza)),7)
FROM
(SELECT user, pizza, COUNT(*) AS freq
FROM user_likes
GROUP BY user, pizza) ilv
GROUP BY user
Let's have a simple solution :
First of all, we have two columns,name and food.
You can list of favorite customer's food easily :
CREATE TEMPORARY TABLE tbltemp AS (
SELECT name, food, COUNT( * ) c
FROM food
GROUP BY name, food
);
Now we have all of foods by count.
Then you can order it by count descending :
SELECT *
FROM tbltemp
ORDER BY c DESC
Now you have a list that describes your customer's favorite.
UPDATE :
Instead of second query ,replace this one :
SELECT tbl1 . *
FROM (
SELECT name, food, COUNT( * ) c
FROM food
GROUP BY name, food
) AS tbl1, (
SELECT name, food, COUNT( * ) c
FROM food
GROUP BY name, food
) AS tbl2
WHERE tbl1.c = tbl2.c
AND tbl2.name = tbl1.name
AND tbl2.food = tbl1.food
AND tbl1.c = (
SELECT c
FROM tbltemp
ORDER BY c DESC
LIMIT 1 )
This query result is your question goal.
Table 1 : (Company)
ID Name
1 A
2 B
3 C
Each company (pk = ID) can have one or more employees.
Table 2 : (Employee) (CompanyID referencing ID)
CompanyID EmpID Name
1 1 Joe
1 2 Doe
1 3 Boe
2 4 Lou
3 5 Su
3 6 Ram
Query :
select CompanyID, count(*) from Employee group by CompanyID having count(*) > 1; # Lists companies and their counts.
CompanyID count(*)
1 3
3 2
For this query, I want just one result with the count of distinct CompanyIDs. So, '2' in this case [Companies A and C].
In short, I am looking for number of companies with 2 or more employees.
Is there anyway to get the result without a temp table or a join? I am using MySQL.
Yes:
select count(*) from
(select CompanyID from Employee group by CompanyID having count(*) > 1) v
or for ranges:
select count(*) from
(select CompanyID from Employee group by CompanyID
having count(*) >= 5 and count(*) < 10) v
Yes, it's possible with subqueries:
SELECT COUNT(*)
FROM
( SELECT 1
FROM Employee
GROUP BY CompanyID
HAVING COUNT(*) > 1
) AS grp
or:
SELECT COUNT(DISTINCT CompanyID)
FROM Employee AS e
WHERE EXISTS
( SELECT *
FROM Employee AS e2
WHERE e2.CompanyID = e.CompanyId
AND e2.EmpID <> e.EmpID
)
or perhaps if COUNT(*) is slow, you can use MIN() and MAX():
SELECT COUNT(*)
FROM
( SELECT 1
FROM Employee
GROUP BY CompanyID
HAVING MAX(EmpID) > MIN(EmpId)
) AS grp