A question for homework is to show the total amount of houses with multiple presents. The list below shows which ones they are but I cannot work out the query to show them as a total of 6. I am still new and learning Mysql, my apologies for the ignorance.
Mysql data
**address** **Number of presents per home**
2 Bay Road 2
2a Neptune Road 2
45 Bay Road 2
59 Black Street 2
65 Mainway Avenue 3
89 White Street 2
Query used:
SELECT address, SUM(goodBehaviour) AS `Number of Houses with Multiple presents`
FROM wishlist
GROUP BY address
HAVING SUM(goodBehaviour) >1;
I have tried a few other queries to total the Address column but have not been able to show my desired output. Thanks.
The problem is that you sum the goodBehaviour field's values, but you should count the number of addresses that have more than 1 presents.
If each address has just 1 record in your table (based on your sample data):
select count(address)
from wishlist
where goodBehaviour >1
If you can have multiple records for a single address, then in a subquery you need to sum the number of presents and count the number of addresses in the outer query, where the total number of presents are more than 1:
select count(address)
from
(select address, sum(goodBehaviour) as presents
from wishlist
group by address) t
where t.presents>1
If you need total number of houses - you can use your query as subquery:
SELECT count(*) FROM (SELECT address, SUM(goodBehaviour) AS `Number of Houses with Multiple presents`
FROM wishlist
GROUP BY address
HAVING SUM(goodBehaviour) >1) x;
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 did a query (pretty simple, with 4 columns x 100 000 rows) and there are redundancies (rows appear several times).
I'd like to add a column that counts the number of times each row appears, and then remove the duplicates. So I don't lose information by adding this "count" column, and in the mean time lighten the table by deleting duplicate rows.
For instance if I have this table:
name
country
price
table
France
12
desk
Italy
8
table
France
12
desk
Italy
8
desk
Italy
14
desk
Italy
8
And the output should be like:
name
country
price
count
table
France
12
2
desk
Italy
8
3
desk
Italy
14
1
To count how many occurrences of a record that appears in a table, you can use the GROUP BY command, this will count how many occurrences depending on what you want to group by.
For instance, if you GROUP BY country then it will count how many records were found for each country.
Example: SELECT name, country, price, COUNT(*) FROM tablename GROUP BY name;
You can read up on GROUP BY here
This query should work for you:
select `name`, `country`, `price`, count(*) from MyTable
group by `name`, `country`, `price`
I have a table with 3 fields, touristic places, the country they're in and the average rating by tourists for this place. I would like to compare different countries based on the average rating of their top touristic places. I use MySQL
It looks like this basically :
Eiffel Tower | France | 4,2
Trakoscan Castle | Croatia | 4,6
For example, how does the average of the notes of the 5 best touristic places in France compare with the average of the notes of the 5 best touristic places in Croatia. I know how to average all places for a country and compare that but I don't know how to combine LIMIT and GROUP BY
Thank you for your help.
You can use window functions to filter on the top 5 notes per country, then aggregate.
Assuming that your table has columns country, place and rating, you would phrase the query as:
select country, avg(rating) avg_rating_top5
from (
select t.*,
row_number() over(partition by country order by rating desc) rn
from mytable t
) t
where rn <= 5
group by country
Note that window functions are available in MySQL 8.0 only.
I have a table of flights, which have an origin and destination city, represented as a foreign id.
A very simplified example of this table looks like:
id | origin | destination
023 1 3
044 3 2
332 2 1
509 1 3
493 1 4
I need to get the first time that a city shows up as an origin or a destination; a list of all the flights that contain a city that hasn't been flown to or from yet.
What I would like to get for the above example would be:
023: 1, 3
044: 2
493: 4
Flights 332 and 509 aren't in the output because they only visit cities that have already been visited.
Here's what I've tried:
(SELECT distinct(origin), distinct(destination) FROM flights ORDER BY id)
Doesn't work because you can't select more than one distinct column
SELECT (distinct(origin) FROM flights ORDER BY id) UNION (distinct (destination) FROM flights ORDER BY id)
Doesn't work because of syntax errors, but mainly because it doesn't take into account that a city should be unique in the origin and destination columns.
If there's not a quick way to do this in SQL I'm also happy to just iterate through and keep track of cities that have been visited (this app has literally one user, and he doesn't care about a few milliseconds of computation because he's over 80), but I'd love to know just so that I can learn more about SQL!
This does it:
SELECT id, GROUP_CONCAT(city ORDER BY city) cities
FROM (
SELECT city, min(id) id
FROM (
SELECT origin city, MIN(id) id
FROM flights
GROUP BY city
UNION
SELECT destination city, MIN(id) id
FROM flights
GROUP BY city) u
GROUP BY city) x
GROUP BY id
DEMO
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.