Count how many times distinct values repeat in another column with sql - mysql

so I got a column with hundreds of different first names and another column with 7 different neighborhoods that repeat multiple times.
I want to check what are the most common names for each neighborhood. How would I go about it?
Thanks and I hope I made my question clear enough.
I tried the below, and got this error - SQL Error: Syntax error: Encountered " "COUNT" "Count "" at line 8, column 5. Was expecting: EOF
SELECT
host_name, neighbourhood_group,
COUNT(*) AS Ct
FROM AB_NYC_2019
GROUP BY
host_name,
neighbourhood_group,
Max Count AS
(
SELECT
*,
MAX(Ct) OVER
(
PARTITION BY neighbourhood_group
) AS MaxCt
FROM Counts
)
SELECT
neighbourhood_group,
host_name
FROM MaxCounts
WHERE Ct = MaxCt;

select * from
(select host_name,neighbourhood_group, RANK() OVER (PARTITION BY neighbourhood_group order by c desc) as RN
from(select host_name,neighbourhood_group,count(*) as c
from AB_NYC_2019 group by host_name,neighbourhood_group)m)n where
RN=1;

Related

Adding Serial Number in mysql successfully but unknown column when use in where clause

I have a table in which I fetch results according to winning in descending order. But I need id for Load More function.
I have successfully added serial number but for load more function i want to use serial number id to get the result and not repeating the result. But when I use into where clause I get error unknown column.
Any help would be appreciated.
I have deleted the stuff, as I post my answer.
try this
select * from (
SELECT rank()over(order by pic_wins desc) as serial_number,
pic_id,
pic_caption,
pic_image,
pic_wins
FROM pics
WHERE pic_status = '1'
order by pic_wins desc
) as foo
where serial_number=1;
you can't use alias in where clause but you can use it an sub query
And if you want continuous series in serial_number use dense_rank()
Thanks for everyone, I got my answer to little modify #dgnk answer
select * from ( SELECT #s:=#s+1 serial_number, pic_id, pic_caption, pic_image, pic_wins FROM pics, (SELECT #s:= 0) AS s WHERE pic_status = '1' order by pic_wins desc ) as foo where serial_number > 8

MySQL - GROUP BY, select only the first row when grouping

I'm having a problem with grouping specific columns into one. When I use GROUP BY, the last row always gets selected when it should be the first row.
The main query is:
SELECT cpme_id,
medicine_main_tbl.med_id,
Concat(med_name, ' (', med_dosage, ') ', med_type) AS Medicine,
med_purpose,
med_quantity,
med_expiredate
FROM medicine_main_tbl
JOIN medicine_inventory_tbl
ON medicine_main_tbl.med_id = medicine_inventory_tbl.med_id
WHERE Coalesce(med_quantity, 0) != 0
AND Abs(Datediff(med_expiredate, Now()))
ORDER BY med_expiredate;
SELECT without GROUP BY
If I GROUP BY using any duplicate column value (in this case, I used med_id):
SELECT with GROUP BY
I'm trying to get this output
Expected Output
The output should only be the first two from the first query. Obviously, I cannot use LIMIT.
Since you are using MariaDB, I recommend using ROW_NUMBER here:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY med_id ORDER BY med_expireDate) rn
FROM yourTable
)
SELECT cpme_id, med_id, Medicine, med_purpose, med_quantity, med_expireDate
FROM cte
WHERE rn = 1;
This assumes that the "first" row for a given medicine is the one having the earliest expire date. This was the only interpretation of your data which agreed with the expected output.

how to count total record using Union All in mysql

select count(*) from ((select count(*) from employee )
union ALL (select count(*) from events)) as total
this is my query i am trying to find ttoal record by given two query
this query
`select count(*) from employee`
give 300 record and
select count(*) from events
this give 100 when i try to count total record then it give always 2 record can any one tell me how to count total record by give query
You can just add together the two counts directly, no need for a UNION query:
SELECT (SELECT COUNT(*) FROM employee) + (SELECT COUNT(*) FROM events) AS total
Note that this will work because you used UNION ALL, which retains all the records in each side of the query. If you wanted to use a UNION then it would look like this:
SELECT COUNT(*) AS total
FROM
(
SELECT * FROM employee
UNION ALL
SELECT * FROM events
) t
But this would only work if the two tables have the same number (and ideally types) of columns. I would probably go with the first option in any case.
select
count(*) result.union_total
from (
(select 1 from table1)
union all
(select 1 from table2)
) result
Use this command:
SELECT
COUNT(*) AS total
FROM
(SELECT * FROM db_domains where id=695
UNION ALL
SELECT * FROM db_domains where id=694
) AS A;
Result: total: 2 ( According my sql table )
Be sure that:
1.The used SELECT statements have a same number of columns.
Otherwise you will get this error:
Error Code: 1222. The used SELECT statements have a different number of columns
2.Every derived table must have its own alias.
Otherwise you will get this error :
Error Code: 1248. Every derived table must have its own alias
See the snapshot in MYSQL Workbench. ( I have tested on workbench ):
In The last snapshot: You can see the result is: 1106

Breaking the results of an sql like query into groups by percentiles : In Redshift / postgresql

I have a collection of group_name with their counts. Say this comes from the statement as below -:
--sample input set --
select group_name, count(*) as group_count
from mytable group by group_name
order by group_count desc ;
group_name group_count
A 205
B 200
C 67
D 55
E 50
F 12
and so on..
What I want is to organize the results of groups_counts with their group names into 3 groups, say Head, core & tail - where each group is understood to be in 33% of the total group_count.So 10, 5 and so on will be replaced by their respective percentiles. And all of this I need to do in redshift(postgres 8.0.2 )
As a first level, it should be something like,
-- this is not a valid syntax--
select case when group_count >10 then group_name end ) as Head_group,
case when group_count >5 and group_count <10 then query end ) as core_group,
case when group_count <5 then group_name end ) as tail_group,
from
( select group_name, count(*) as group_count
from mytable group by group_name
order by group_count desc ) ;
In the required syntax the selections would be based on sum(group_count) - which will be the total of all group counts. How would I get the same in postgressql , more specifically in Redshift.
Note that create function is not supported in Redshift. Also prepare & set is available but not prepare statement in Redshift.
--sample output set---
Head_group core_group tail_group
A D F
B E
C
--Alternative sample output set---
Head_group
A
B
C
core_group
D
E
tail_group
F
Note that each group can have a different number of rows returned.
in mysql, I could do something like-:
set #total_group_count =(select count(*) from mytable ) ;
set #percentile_group_count = ( select #total_group_count*(30/100)) ;
Reference to my related question :
Storing the results of a prepared statement as a table in mysql?
The ntile window function is what you most likely want to use here.
It could be used something like this with your query:
select group_name, count(*) as group_count,
ntile(3) over(order by group_count desc) AS group_ntile
from mytable group by group_name
order by group_count desc;
That should divide the (descending) value of the group_count column into three equal groups. You could then use the group_ntile value in you CASE statements to do what you want based on which group it's in.
Based on the Redshift doc, it does appear that ntile is available.
Edit in response to comment from OP:
The argument to ntile is the number of ranking groups.
i.e. ntile will bucket the results (using the specified window function parameters) into the number of groups specified in the argument to the function. So, if you want true percentiles, then you should use ntile(100).

Average on a count() in same query

I'm currently working on an assignment which requires me to find the average on the number of resources for each module. The current table looks like this:
ResourceID ModulID
1 1
2 7
3 2
4 4
5 1
6 1
So basically, I'm trying to figure out how to get the average number of resources. The only
relevant test data here is for module 1, which has 3 different resources connected to it. But I need to display all of the results.
This is my code:
select avg(a.ress) GjSnitt, modulID
from
(select count(ressursID) as ress
from ressursertiloppgave
group by modulID) as a, ressursertiloppgave r
group by modulID;
Obviously it isn't working, but I'm currently at loss on what to change at this point. I would really appreciate any input you guys have.
This is the query you are executing, written in a slightly less obtuse syntax.
SELECT
avg(a.ress) as GjSnitt
, modulID
FROM
(SELECT COUNT(ressursID) as ress
FROM ressursertiloppgave
GROUP BY modulID) as a
CROSS JOIN ressursertiloppgave r <--- Cross join are very very rare!
GROUP BY modulID;
You are cross joining the table, making (6x6=) 36 rows in total and condensing this down to 4, but because the total count is 36, the outcome is wrong.
This is why you should never use implicit joins.
Rewrite the query to:
SELECT AVG(a.rcount) FROM
(select count(*) as rcount
FROM ressursertiloppgave r
GROUP BY r.ModulID) a
If you want the individual rowcount and the average at the bottom do:
SELECT r1.ModulID, count(*) as rcount
FROM ressursertiloppgave r1
GROUP BY r1.ModulID
UNION ALL
SELECT 'avg = ', AVG(a.rcount) FROM
(select count(*) as rcount
FROM ressursertiloppgave r2
GROUP BY r2.ModulID) a
I got the solution
SELECT AVG(counter)
FROM
(
SELECT COUNT(column to count) AS counter FROM table
) AS counter
Note that the nickname {counter} was added in SELECT COUNT and at the end of the inner SELECT