Count occurrences of distinct values - mysql

I am trying to find a MySQL query that will display the number of occurrences of an ID value within a year.
Table:
a_id year
---- ----
1 2010
1 2011
1 2012
1 2012
1 2013
1 2014
1 2015
2 2010
2 2011
2 2013
2 2014
2 2014
2 2015
3 2010
3 2010
3 2011
Expected output:
a_id year occurrences
---- ----- -----------
1 2010 1
1 2011 1
1 2012 2
1 2013 1
1 2014 1
1 2015 1
2 2010 1
2 2011 1
2 2013 1
2 2014 2
2 2015 1
3 2010 2
3 2011 1
I'm trying with the something along the lines of following sql query, but it gives me nothing like the expected output. It's the 3rd column im struggling with.
SELECT a__id, year, count(distinct a_id) as occurrences
FROM table1
GROUP by year
ORDER by a_id
How can i create that 3rd column?

Scince you are grouping by a_id and year you of course get only 1 distinct value for group. Simply change count(distinct a_id) to count(*).
For example you get group:
1 2012
1 2012
Notice in this group distinct a_id values is 1. But you want count of all rows in group. With distinct you will get 1 as occurence in all groups.
EDIT:
Ok, I have missed that you are grouping only by year, so you should group by a_id also. The rest of the answer stays as is. So you end up with:
SELECT a__id, year, count(*) as occurrences
FROM table1
GROUP by a__id, year

SELECT a__id, year, count(*) as occurrences
FROM table1
GROUP by a__id, year

Using the following will get you what you are looking for.
SELECT a_id, year, count(*)
FROM table1
GROUP BY a_id, year
ORDER BY a_id, year
Although, in previous versions, ORDER BY may have been guaranteed by MySQL, it is deprecated now. If you want to ensure your results come back sorted, add ORDER BY. 'Future you' will thank you for it.

Related

MYSQL - Select count with group by with only a table

I have these data
idhouse year
7 2016
2 2018
2 2017
3 2017
4 2015
14 2003
3 2018
5 2018
4 2017
4 2018
I want to counting the number of houses belong to two years.
I tried with mysql select but didn't work.
How I should do it?
EDITED
Sorry for my bad explanation.
I have only one mysql table.
Filtering by 2017 and 2018 and count the numbrer these houses, I should get these match:
idhouse year
7 2016
2 2018*
2 2017*
3 2017*
4 2015
14 2003
3 2018*
5 2018
4 2017*
4 2018*
And the SELECT should be show 3
I assume a house can only appear once in a year. Try this:
SELECT
COUNT(*) nb_houses
FROM (SELECT house
FROM yourTable
GROUP BY house
HAVING COUNT(*)>1) A;
See this run on SQL Fiddle.
Assuming a PK on (house,year), if you just want to know how many houses are listed more than once, you can do this...
SELECT COUNT(DISTINCT x.house) total
FROM my_table x
JOIN my_table y
ON y.house = x.house
AND y.year <> x.year;
I asuming you're doing a web app with this question
SELECT house, COUNT(year) as count_year FROM table GROUP BY house HAVING COUNT(year) = 2
By using your data above, the result will be
house | count_year
____2 | _______2
Then if you are using server side scripting like PHP use mysqli_num_rows for get the number of row(s).
Or if you use other language, just adjust the algorithm to get the number of row(s)
With this Select I get it:
select count(*) from (select house from yourTable Where year = 2018 and house in (select house from yourTable where year = '2017')) A;
But can we improve this Select in terms of efficiency?
You can try here
Thanks.

Check if instances have occurred minimum once, every year in a specific range

In MySQL I'm tasked with a big dataset, with data from 1970 to 2010.
I want to check for consistency: check if each instance occurs minimum one time per year. I took a snippet from 1970-1972 as example to demonstrate my problem.
input:
id year counts
-- ---- ---------
1 1970 1
1 1971 1
2 1970 3
2 1971 8
2 1972 1
3 1970 4
expected:
id 1970-1972
-- ----------
1 no
2 yes
3 no
I though about counting within the date range and then taking those out who had 3 counts: 1970, 1971, 1972. The following query doesn't force the check on each point in the range though.
select id, count(*)
from table1
WHERE (year BETWEEN '1970' AND '1972') AND `no_counts` >= 1
group by id
What to do?
You can use GROUP BY with CASE / inline if.
Using CASE. SQL Fiddle
select id,CASE WHEN COUNT(distinct year) = 3 THEN 'yes'ELSE 'No' END "1970-72"
from abc
WHERE year between 1970 and 1972
GROUP BY id
Using inline IF. SQL Fiddle
select id,IF( COUNT(distinct year) = 3,'yes','No') "1970-72"
from abc
WHERE year between 1970 and 1972
GROUP BY id
You can use a having clause with distinct count:
select `id`
from `table1`
where `year` between '1970' and '1972'
group by id
having count(distinct `year`) = 3
Do you expect this?
select id, count(*)
from table1
WHERE (year BETWEEN '1970' AND '1972')
group by id
having count(distinct year) = 3

Retrieve data from Sql Table according to described scenario

I have a database table with following columns
Id, Name, Date (FORMAT: Y-m-d H:i:s)
Now I want to retrieve data of following form
Count Year
3 2013
5 2014
It is showing total no of records generated in different years
For example If I have following data:
1 Manish 2013-10-01 23:12:12
2 Tarun 2013-10-02 23:12:12
3 Pankaj 2014-10-02 23:12:12
4 Pankaj 2015-10-02 23:12:12,
Then it will return me following data:
Count Year
2 2013
1 2014
1 2015
Is it possible?
select count(*) as cnt,
year(date) year_of_date
from your_table
group by year_of_date
select year(date) as Year,count(*) as Total
from my_table
group by year(date)

Select all rows with certain year, plus all rows of affected group

I have a table in which each hundret rows have the same id (see "chart_id" in shortened Example below).
If we consider every row with the same "chart_id" a "chart" how do I select every chart having a certain year in it with a mysql query.
For example how do I select every chart with 2009 in it (chart2 and chart3):
edit:
rows with id 4,5,6 and 7,8,9 should be selected if I look for 2009.
id chart_id time
1 1 2008
2 1 2008
3 1 2008
4 2 2008
5 2 2008
6 2 2009
7 3 2009
8 3 2009
9 3 2009
10 4 2010
11 4 2010
12 4 2010
Any suggestions?
Thanks :)
Just use DISTINCT:
SELECT DISTINCT chart_id
FROM myTable
WHERE time = 2009
Or, do you mean you want all the rows for that chart SQL Fiddle:
SELECT *
FROM myTable t1
WHERE EXISTS(SELECT 1
FROM myTable t2
WHERE t2.chart_id = t1.chart_id AND t2.time = 2009)
Seems like a SELECT DISTINCT chart_id WHERE year ... would work.
SELECT DISTINCT chart_id FROM table_name WHERE time = 2009

MySQL Order year field by closest match

I'm trying to order some dates so that they are listed in a particular order closest to a specified date:
id year
---------
1 2010
2 2011
3 1992
4 1996
5 1987
6 1988
The result should look like (if I specify 1992 as the year to order by):
id year
---------
3 1992
4 1996 <4 away
5 1987 <5 away
6 1988 <6 away
1 2010 <8 away
2 2011 <9 away
I want it so that it returns all dates, but the most relevant (closest) first in the list.
Sorry I have revised my question to make it more clear what I'm trying to achieve.
Am I missing something? Isn't it just:
SELECT *
FROM table
WHERE year >= '1992'
ORDER BY year ASC
Then to edit I guess...
SELECT *, ABS(year - 1992)
FROM table
ORDER BY ABS(year-1992) ASC
I think that will work
This should solve your problem.
SELECT *
FROM `table`
ORDER BY ABS(1992-`year`) ASC