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.
Related
I have a table
Films
id release_year category_id rating
1 2015 1 8
2 2015 2 8.5
3 2015 3 9
4 2016 2 8.2
5 2016 1 8.4
6 2017 2 7
I want to add a new column "avg_better_films" to find an average rating of all better films in its release year
the output should be
id release_year category_id rating avg_better_films
1 2015 1 8 8.75
2 2015 2 8.5 9
3 2015 3 9 Not Available
4 2016 2 8.2 8.4
5 2016 1 8.4 Not Available
6 2017 2 7 Not Available
and you can see, when the film has the best rating in the release year
it will show "Not Available"
Do you know how to get this output in MySQL
We can use a Correlated Subquery to calculate the Average rating for the "better films" for the same year.
Subquery would return null in case of no better films for a specific film and year.
We can then use Coalesce() function to handle the case when there is no "better film" found for the year.
Thanks to #Strawberry in comments, we need to do + 0 to the result of subquery, so that MySQL considers it as number
Try the following:
SELECT
t1.id,
t1.release_year,
t1.category_id,
t1.rating,
COALESCE(
(
SELECT AVG(t2.rating)
FROM Films AS t2
WHERE t2.rating > t1.rating AND -- higher rating films
t2.release_year = t1.release_year -- films from same year
) + 0,
'Not Available' -- handle null result of subquery
) AS avg_better_films
FROM Films AS t1
SQL Fiddle: http://sqlfiddle.com/#!9/4960ea/3
you can try using scalar subquery
select *, (select avg(rating) from Films b on a.release_year=b.release_year) as avg_film_Rating
from Films a
This is tricky, because you need to output the results as a string, not a number. If any value is a string, all must be.
I would recommend a correlated subquery that looks like:
SELECT f.*,
(SELECT COALESCE(FORMAT(AVG(t2.rating), 2), 'Not Available)
FROM Films f2
WHERE f2.rating > f.rating AND
f2.release_year = f.release_year
) AS avg_better_films
FROM Films f
Notes:
Table aliases should be abbreviations for the table name.
If no rows match the WHERE clause in the subquery, then AVG() returns NULL. Hence, the COALESCE()can be in the subquery.
FORMAT() is used to convert the average rating to a string.
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
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.
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
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