I'm having a hard time wording what I need/wording the search result, so apologies if this is a stupid question/has been answered before. I'm trying to write a query in SQL for a table such as below:
Country Unique_ID
US 123
US 124
UK 125
Australia 126
That will output the follow table:
Country Count_Distinct
US 2
UK 1
Australia 1
All 4
I know I can select the countryid and count distinct the country codes, and I know I can just count distinct the countryid codes to get the "All" number. I can't figure out how to write a query to get the follow output that's not two separate queries.
If you need information or clarification please let me know. Thanks!
Use WITH ROLLUP:
select Country, count(distinct Unique_ID) Count_Distinct
from mytable
group by Country
with rollup
If you want the text "All" (you get a null for the country by default), wrap it in another query to change the null to "All":
select coalesce(Country, "All") Country, Count_Distinct
from (
select Country, count(distinct Unique_ID) Count_Distinct
from mytable
group by Country
with rollup
) x
Can you please try this :
select country,count(distinct unique_id) as count distinct
from table
group by rollup(country)
Related
I have a simple db where I have users and every user have 'country', for ex:
Dmitry - US
Ann - US
John - UK
Roman - Japan
Mila - China
Jane - Australia
I want to get count of very country users, BUT I need to get TOP 3 countries users counts (US, UK, Japan for example), and all other countries users count should be summarized together as "Rest". How to do this?
So in my example this should give me this result from SQL:
US = 2
UK = 1
Japan = 1
Rest = 2
If I will make regular SQL:
SELECT count(userid) FROM users GROUP BY country
I will get results for every country, but I need only TOP 3 and all others count as "Rest" in results. Thanks!
P.S.: I tried to create SQLFiddle for this, but their website is down right now and I can't use it.
You can group by country and use ROW_NUMBER() window function to rank the countries based on the number of times they appear.
Then add another level of aggregation based on the ranking position of each country:
SELECT CASE WHEN rn <= 3 THEN country ELSE 'Rest' END country,
SUM(counter) counter
FROM (
SELECT country, COUNT(*) counter,
ROW_NUMBER() OVER (ORDER BY COUNT(*) DESC) rn
FROM users
GROUP BY country
) t
GROUP BY 1;
Note that the countries returned as top 3 in case of ties may be arbitrary chosen, so you could add another condition in the ORDER BY clause of ROW_NUMBER(), like:
ROW_NUMBER() OVER (ORDER BY COUNT(*) DESC, country)
which would return different but consistent results.
See the demo.
I Have tables like below
How is query to show summary data like above?
NB: I was try, but my query result INDIA is 3. What i mean is only count company on period without count project with that period, so that the right result should is 2 like above
Thank You
You can try this
DEMO
Select countryname, count(distinct a.id_company) as sumval
from company a inner join project b on a.id_company=b.id_company
where b.period='2017'
group by countryname
OUTPUT:
countryname sumval
Franch 1
India 2
Sorry, the title might be a bit hard to understand. I'm studying MySQL at school but right now I'm stuck in an exercise and I'm not able to find the solution anywhere around (although I'm 100% sure it's out there, I just can't find it).
Anyway, I have a table with some medical departments that go by the name of Psychiatry, Surgeon and Dermatologist. Both the surgeon and psychiatry areas have 2 medics in them, and dermatologist has just one. I'm supposed to get the name of the area with the most medics, simple as that. The problem I have is that I can't get BOTH areas to appear, just one of them or all of them. This is my code:
select speciality, count(*)
from medics
group by speciality
order by count(*);
I've also tried with:
select max(total), speciality
from
(select speciality, count(*) as 'total' from medics
group by speciality
order by count(*))
as test
group by speciality;
EDIT: This is the table where I must take the data from:
cod_hospital dni apellidos epecialidad
4 22233311 Martínez Molina, Gloria PSIQUIATRA
2 22233322 Tristán García, Ana CIRUJANO
2 22233333 Martínez Molina, AndrEs CIRUJANO
4 33222111 Mesa del Castillo, Juan DERMATOLOGO
1 66655544 Castillo Montes, Pedro PSIQUIATRA
And this is the expected result. "1 - DERMATOLOGO" result shouldn't appear there since that's not the speciality with the most medics:
max(total) especialidad
2 CIRUJANO
2 PSIQUIATRA
E.g.:
SELECT a.*
FROM
(SELECT especialidad,COUNT(*) total FROM medics GROUP BY especialidad) a
JOIN
(SELECT COUNT(*) total FROM medics GROUP BY especialidad ORDER BY total DESC LIMIT 1) b
ON b.total = a.total;
Yes. It really can be that crude sometimes.
I want to concatenate fields intersected part of the same table
id user_id user_ip
4 971 108.54.218.114
5 972 108.54.218.114
6 973 108.54.218.114
7 974 108.54.218.114
8 975 107.222.159.246
9 975 98.54.818.133
In the example above, we can see that the user with the IP address (108.54.218.114) address to create multiple accounts with the following account IDs (971, 972, 973, 974), but also that the user with the account ID (975) is connect from the following IP addresses (107.222.159.246, 98.54.818.133)
I want to format the results like this
user_id user_ip
971,972,973,974 108.54.218.114
975 107.222.159.246, 98.54.818.133
MySQL
SELECT
GROUP_CONCAT(DISTINCT users_log.user_id) AS ID_LOG,
GROUP_CONCAT(DISTINCT users_log.user_ip) AS IP_LOG
FROM users_log
GROUP BY users_log.user_id
ORDER BY users_log.user_id DESC
If anyone can help me?
Thank you in advance for your help
There is another recent question (which I can't find) on SO very close to this. I asked about the intersecting row because of the (for lack of better term) recursiveness of this type of solution.
Here is SQL to give you your exact answer for that exact sample set.
SELECT user_id, GROUP_CONCAT(DISTINCT user_ip) AS user_ip
FROM users_log
GROUP BY user_id
HAVING COUNT(*) >1
UNION
SELECT GROUP_CONCAT(DISTINCT user_id) AS user_id, user_ip
FROM users_log
GROUP BY user_ip
HAVING COUNT(*) >1;
I can't seem to find a suitable solution for the following (probably an age old) problem so hoping someone can shed some light. I need to return 1 distinct column along with other non distinct columns in mySQL.
I have the following table in mySQL:
id name destination rating country
----------------------------------------------------
1 James Barbados 5 WI
2 Andrew Antigua 6 WI
3 James Barbados 3 WI
4 Declan Trinidad 2 WI
5 Steve Barbados 4 WI
6 Declan Trinidad 3 WI
I would like SQL statement to return the DISTINCT name along with the destination, rating based on country.
id name destination rating country
----------------------------------------------------
1 James Barbados 5 WI
2 Andrew Antigua 6 WI
4 Declan Trinidad 2 WI
5 Steve Barbados 4 WI
As you can see, James and Declan have different ratings, but the same name, so they are returned only once.
The following query returns all rows because the ratings are different. Is there anyway I can return the above result set?
SELECT (distinct name), destination, rating
FROM table
WHERE country = 'WI'
ORDER BY id
Using a subquery, you can get the highest id for each name, then select the rest of the rows based on that:
SELECT * FROM table
WHERE id IN (
SELECT MAX(id) FROM table GROUP BY name
)
If you'd prefer, use MIN(id) to get the first record for each name instead of the last.
It can also be done with an INNER JOIN against the subquery. For this purpose the performance should be similar, and sometimes you need to join on two columns from the subquery.
SELECT
table.*
FROM
table
INNER JOIN (
SELECT MAX(id) AS id FROM table GROUP BY name
) maxid ON table.id = maxid.id
The problem is that distinct works across the entire return set and not just the first field. Otherwise MySQL wouldn't know what record to return. So, you want to have some sort of group function on rating, whether MAX, MIN, GROUP_CONCAT, AVG, or several other functions.
Michael has already posted a good answer, so I'm not going to re-write the query.
I agree with #rcdmk . Using a DEPENDENT subquery can kill performance, GROUP BY seems more suitable provided that you have already INDEXed the country field and only a few rows will reach the server. Rewriting the query giben by #rcdmk , I added the ORDER BY NULL clause to suppress the implicit ordering by GROUP BY, to make it a little faster:
SELECT MIN(id) as id, name, destination as rating, country
FROM table WHERE country = 'WI'
GROUP BY name, destination ORDER BY NULL
You can do a GROUP BY clause:
SELECT MIN(id) AS id, name, destination, AVG(rating) AS rating, country
FROM TABLE_NAME
GROUP BY name, destination, country
This query would perform better in large datasets than the subquery alternatives and it can be easier to read as well.