Here are two table with schema:
Ships(name, yearLaunched, country, numGuns, gunSize, displacement)
Battles(ship, battleName, result)
A typical Ships tuple would be:
('New Jersey', 1943, 'USA', 9, 16, 46000)
which means that the battleship New Jersey was launched in 1943; it belonged to the USA, carried 9 guns of size 16-inch (bore, or inside diameter of the barrel), and weighted (displaced, in nautical terms) 46,000 tons.
A typical tuple for Battles is:
('Hood', 'North Atlantic', 'sunk')
That is, H.M.S. Hood was sunk in the battle of the North Atlantic. The other possible results are 'ok' and 'damaged'.
And here is the tricky query:
For the battle of Surigao Strait, for each country engaged in that battle (had one or more battleships participating), give the number of its battleships that were sunk. Note: this question is very tricky. In particular, you need to deal with the (historical) case that a country engaged in the battle but did not have any ships sunk.
What I've tried so far.
SELECT country,COUNT(name)
FROM ships RIGHT JOIN battles
ON ships.name=battles.ship
WHERE battleName='Battle1' AND result='sunk'
GROUP BY country
country engaged in that battle (had one or more battleships
participating)
It means has at least one record in the battles where the battleName is 'Surigao Strait'. It means an INNER JOIN.
give the number of its battleships that were sunk
It is a conditional count, and here is the "trick". You can use a SUM with a condition end then you can have the count of the ships sunk.
SELECT country,SUM(CASE WHEN result = 'sunk' THEN 1 ELSE 0 END) AS TotalShipSunk
FROM ships
INNER JOIN battles
ON ships.name=battles.ship
WHERE battleName='Surigao Strait'
GROUP BY country
You need to join the tables and I guess the relationship with is other is by name of the ship. try this one,
SELECT a.country,
SUM(CASE WHEN b.result = 'SUNK' THEN 1 ELSE 0 END) totalSunkShips,
SUM(CASE WHEN b.result = 'OK' THEN 1 ELSE 0 END) totalUNSunkShips
FROM battles a
INNER JOIN ships b
ON a.ship = b.name
WHERE b.battleName = 'Surigao Strait'
GROUP BY a.country
Sample Ships Record
name yearLaunched country numGuns gunSize displacement
New Jersey 1943 USA 9 16 46000
Surigao Strait Battle ship USA 1800 USA 9 16 5000
Surigao Strait Battle ship USA 1800 USA 9 16 5000
Surigao Strait Battle ship UK 1800 UK 7 16 27000
Surigao Strait Battle ship France 1800 France 9 16 5000
Surigao Strait Battle ship Urugaya 1800 Urugaya 7 16 27000
New Jersey 1943 UK 9 16 46000
Sample Battle Record
ship battleName result
Hood North Atlantic sunk
Surigao Strait Battle ship USA Surigao Strait sunk
Surigao Strait Battle ship UK Surigao Strait damaged
Surigao Strait Battle ship France Surigao Strait ok
Surigao Strait Battle ship Urugaya Surigao Strait sunk
Is this what you are looking for
SELECT s.country,Count(s.name) AS Cnt
FROM ships s
JOIN (SELECT *
FROM Battles
WHERE battleName='Surigao Strait' AND result='sunk' )b
ON s.name=b.ship
GROUP BY s.country
Result
country Cnt
Urugaya 1
USA 2
Related
I just started coding using sql. This is an example of correlated- subquery I an struggling with; Can anyone please explain in layman terms whats going on here:
SELECT id
FROM flights AS f
WHERE distance > (SELECT AVG(distance)
FROM flights
WHERE carrier = f.carrier);
Your query is semantically identical to the following, which (personally) I find easier to read. (I suspect it's fractionally faster too)...
SELECT id
FROM flights g
JOIN
( SELECT carrier
, AVG(distance) avg_distance
GROUP
BY carrier
) x
ON x.carrier = f.carrier
AND x.distance > avg_distance;
Your query returns all flights, where the distance is bigger than average distance of that particular carrier.
An example:
id flight carrier distance
1 Brussels Swiss 200
2 New York Swiss 2000
3 Berlin Lufthansa 300
4 London Lufthansa 400
average distance of Swiss is 1100 and of Lufthansa is 350
And your query returns:
2
4
Flight 2 is of carrier Swiss and its distance 2000 is bigger than the average distance of Swiss with 1100.
Flight 4 is of carrier Lufthansa and its distance 400 is bigger than the average distance of Lufthansa with 350.
The table name is c_list.
Country City Rating Date
------------------------------------
France Brest 95 24092016
France Brest 98 27092016
France Brest 95 03102016
France Lille 100 26092016
France Lille 92 28092016
Japan Tokyo 98 02102016
There are more than 50 different countries and each country have few cities. And each city may have more than one row of record or more. I want to select one City with highest average Rating (Compare to Cities in it's own country) and then compare with all other cities in different countries. So, the final query should display all Country and their ONE City with max(avg(Rating)) and in desc order. The sample output:
Country City max(avg(rating))
-------------------------------------
USA New York 97.25
UK Cardiff 96.70
Germany Greven 96.50
Turkey Afyon 94.88
France Guipavas 94.10
Canada Cartwright 91.35
I can only get the max(avg(rating)) for one country. Need help.
SELECT top 1 country, city, Avg(rating) AS Ratings
FROM c_list
where country = 'France'
GROUP BY city, country
order by Ratings desc
(Edited) The result that I want is similar like Miss world contest. Compete and win against local contestant in your country first. Next (my final result set) is to compete against the winners from other countries and rank them first to last using their avg(rating) that they got eatlier in their country.
If am not wrong you are looking for this
SELECT country,
city,
Avg(rating) AS Ratings
FROM c_list A
GROUP BY city,
country
HAVING Avg(rating) = (SELECT TOP 1 Avg(rating) AS Ratings
FROM c_list B
WHERE a.country = b.country
GROUP BY city
ORDER BY ratings DESC)
ORDER BY ratings DESC
Note : If you are using Mysql the replace TOP keyword with LIMIT
Base table:
select t.* from temp_lax t
COUNTRY CITY RATING
1 France Brest 95
2 France Brest 98
3 France Brest 95
4 France Lille 100
5 France Lille 92
6 Japan Tokyo 98
Query:
select t1.country, t1.city, Avg(t1.Rating) rating
from temp_lax t1
group by t1.country, t1.city
having avg(t1.rating) = (select max(avg(rating))
from temp_lax t2
WHERE t1.country = t2.country
GROUP BY t2.city)
order by rating desc
OUTPUT:
COUNTRY CITY RATING
1 Japan Tokyo 98
2 France Lille 96
3 France Brest 96
Please let me know if you are looking for different result set.
I have this query result and I would like the second row for each id to be added as a
SELECT m.post_id,m.meta_value,p.post_title
from events_posts p
inner join events_postmeta m
on p.ID=m.post_id and p.post_type='event' and (p.post_status='publish' or p.post_status='recurring')
and(m.meta_key='address' or m.meta_key='st_date')
order by m.post_id
column.
The results right now :
post_id meta_value post_title
15 Carolina Beach Road, Wilmington, NC, United States An Art Exhibition
15 2014-02-03 An Art Exhibition
19 Dakota Street, Winnipeg, MB, Canada Weekly Karate Classes
19 2014-02-06 Weekly Karate Classes
23 Alaskan Way, Seattle, WA, United State Christmas Carnival
23 2014-02-03 Christmas Carnival
I would like it to be
post_id | meta_value| post_title
15 | Carolina Beach Road, Wilmington, NC, United States | An Art Exhibition | 2014-02-03
19 |Dakota Street, Winnipeg, MB, Canada |Weekly Karate Classes |2014-02-06
23 |Alaskan Way, Seattle, WA, United State |Christmas Carnival |2014-02-03
You are actually not trying to convert rows to columns. You are trying to merge two rows of your query into one. This behaviour should be possible through joining the events_postmeta twice.
SELECT p.ID, m1.meta_value as event_address, m2.meta_value as event_date, p.post_title
from events_posts p
inner join events_postmeta m1
on p.ID=m1.post_id and p.post_type='event' and (p.post_status='publish' or p.post_status='recurring')
and m1.meta_key='address'
inner join events_postmeta m2
on p.ID=m2.post_id and p.post_type='event' and (p.post_status='publish' or p.post_status='recurring')
and m2.meta_key='st_date'
order by p.ID
That way the m1-join adds the address as a column and the m2-join adds the date. I could not test this but I am pretty sure it works (modulo some typing syntax mistakes).
I hope you can help me with an SQL statment that I can't seem to figure out.
I have a table with a list of visits made, with the country visited and the dates such as;
United Kingdom, 1st Nov 2009
Germany, 8th June 2010
Frane, 10th September 2011
United Kingdom, 11th october 2011
etc.
I want to extract the data so that I get a table list such as follows
Times Visited - Country list
23 - United Kingdom
10 - France, Germany
4 - Czech Republic, USA, Canada
1 - Poland, Serbia, Argentina, New Zealand
So that the data shows that I have made 4 visist to the Czech Republic, USA & Canda
And the query
select * from
(
select count(*) as "trips", country from trip_view
group by country
order by 1 desc
) as a
returns the data
23 United Kingdom
10 France
10 Germany
4 Czech Republic
4 USA
4 Canada
etc.
So I need a kind of group on the outer SQL, but if I do the following
select * from
(
select count(*) as "trips", country from trip_view
group by country
order by 1 desc
) as a
group by trips
Then I only get 1 entry for each country. i.e.
23 United Kingdom
10 France
4 Czech Republic
etc.
So for each row I only have 1 country listed and not all of them. i.e. Row 2 should show France & Germany and row 3 should show Czech, USA & Canada
Any ideas how to do this in mysql?
Thanks
Using GROUP_CONCAT on the country column it should yield the result you want:
SELECT trips,
GROUP_CONCAT(country) AS country
FROM (
SELECT COUNT(*) AS "trips",
country
FROM trip_view
GROUP BY country
) a
GROUP BY trips
ORDER BY 1 DESC
Output:
TRIPS COUNTRY
23 United Kingdom
10 France,Germany
4 Czech Republic,Canada,USA
Live DEMO.
I have two tables on MySQL (using phpMyAdmin), looking like the following:
Table 1:
Country Total Minutes
USA 100
USA 90
Canada 60
Mexico 80
UK 90
France 70
France 10
Germany 10
In Table 2, what I need to do is the following:
Region Total Minutes
North America USA+USA+Canada+Mexico Mins
Europe UK+France+France+Germany Mins
Is there a way to have a row be the result of a query?
You either need a region column in table 1:
SELECT region, SUM(`Total Minutes`)
FROM timespent
GROUP BY region;
Or a separate region <-> country table:
SELECT region, SUM(`Total Minutes`)
FROM myregions r
INNER JOIN timespent t USING (country)
GROUP BY r.region;
The regions table would look like this:
region | country
--------------+--------
North America | USA
North America | Mexico
If you can't change anything in your database, look at Andomar's solution :)
You could translate the countries to regions in a subquery. The outer query can then group by on region:
select Region
, sum(TotalMinutes) as TotalMinutes
from (
select case country
when 'USA' then 'North America'
when 'France' then 'Europe'
end as Region
, TotalMinutes
from YourTable
) as SubQueryAlias
group by
Region