SQL - Trying to correlate data - mysql

I'm just learning SQL. The data set I have looks like this:
city_name | work_place_name | min_commute_time | max_commute_time
-------------------------------------------------------------------
Austin CONGRESS 25 45
Austin NASA 10 12
Austin CIRCUS 16 35
CEDAR PARK CONGRESS 35 65
CEDAR PARK NASA 28 60
CEDAR PARK CIRCUS 26 55
KYLE CONGRESS 50 85
KYLE NASA 60 100
KYLE CIRCUS 60 100
I'm trying to figure out which city will have a min commute time of less than or equal to 30 for both CONGRESS and NASA. I came up with the following query, but I'm not getting the results that I am looking for.
SELECT city_name
FROM commute_times
WHERE min_commute_time<=30 AND (work_place_name='NASA' OR work_place_name='CONGRESS')
The results that I am getting are:
city_name
-----------
Austin
Austin
Cedar Park
The results that I am hoping for are:
City_name
-----------
Austin

You are close. Aggregation will fill in the missing piece:
SELECT city_name
FROM commute_times
WHERE min_commute_time <= 30 AND
work_place_name IN ('NASA', 'CONGRESS')
GROUP BY city_name
HAVING COUNT(*) = 2;

Related

Retrieve the first and second best win results per age_group column per a region column in mysql table

MySql issue: I want to extract the two best age_groups per region based on their wins. I haven't had much luck on this, having browsed similar issues. It's probably straightforward but mysql isn't playing nice for me this evening.
region
age_group
wins
london
35
52
paris
10
54
dublin
15
57
london
40
65
paris
20
68
dublin
35
73
paris
5
75
london
5
79
dublin
25
81
paris
15
81
london
30
82
dublin
20
83
london
20
85
london
10
87
london
25
87
paris
30
91
paris
25
91
dublin
40
94
dublin
30
96
dublin
5
96
london
15
99
dublin
10
100
Results should like something like this:
region
best_age_category
second_best_age_category
dublin
10
5
london
15
25
paris
25
30
select region
,group_concat(case when dns_rnk = 1 then age_group end) as best_age_category
,group_concat(case when dns_rnk = 2 then age_group end) as second_best_age_category
from (
select *
,dense_rank() over(partition by region order by wins desc) as dns_rnk
from t
) t
group by region
region
best_age_category
second_best_age_category
dublin
10
5,30
london
15
25,10
paris
30,25
15
Use ROW_NUMBER() OVER (<partition_definition> <order_definition>) to assign row numbers to your records and then filter where the row number is 1 or 2

Using a three column unique combination in SQL only once

So, I'm managing a table where it's stored the scores of a particular competition.
The table looks like this:
ENTRY_ID TEAM_ID DATE PLACE SCORE
1 1 2021-10-12 Ireland 64
2 2 2021-10-12 Ireland 31
3 3 2021-10-12 France 137
4 2 2021-10-12 France 61
5 5 2021-10-12 France 38
6 1 2021-10-12 France 66
7 2 2021-10-12 Italy 17
8 3 2021-10-12 Italy 61
9 1 2021-10-12 Italy 74
The competition is held at three different places at the same time, with technically all teams being able to have teams in all of them.
Each team however can only win one point so, in the example, it's possible to see that Team 1 would win both in Italy and Ireland, but it should be awarded only one point for the highest score, so only Italy. The point in Ireland should go to the second place.
The query I was trying to get the results is:
SELECT `TEAM_ID`, `PLACE`
FROM `COMPETITION`
WHERE `date` = "2021-10-12"
GROUP BY `PLACE`
ORDER BY `SCORE` DESC, `id` ASC
LIMIT 3
So I could retrieve all three winners with no further processing.
The results I'm trying to achieve should repeat neither the TEAM_ID nor PLACE, in this particular example it should output:
3 FRANCE (Since it has the highest score in France at 137)
1 ITALY (For the highest score in Italy at 74)
2 IRELAND (For the second-highest score in Ireland, since Team 1 already won in Italy)
The production model of this table has far more entries so it's unlikely there would be any clashes with too many second-places.
How can I achieve that?

Selecting Only the most recent date

I'm having difficulties with a query that absolutely has me stumped. I have a mysql database for a restaurant chain that keeps track of menu item prices from year to year. In this particular query I'm trying to obtain only the most recent price for an item at each store.
ItemMenu
pk storeNum itemNum vendorNum size price year
1 5555 2000 3150 Large 3.99 2015
2 5555 2000 3150 Large 3.75 2014
3 3333 2000 3153 Large 3.69 2014
4 2222 2000 3150 Large 3.89 2014
5 2222 2000 3150 Large 3.69 2013
ItemList
itemNum item categoryNum
2000 Mashed Potatoes 2000
2001 Green Beans 2000
2002 Coleslaw 2000
2003 Baked Beans 2000
2004 Corn 2000
ItemCategory
categoryNum type
2000 Side
2001 Dessert
2002 Drink
2003 Sauce
ItemVendor
vendorNum vendorName
3150 Acme Foods
3152 John's Vegetables
3153 Smith's Wholesale
Stores
storeNum franchisee address phone
5555 David Smith 9999 Main st 555-1212
3333 James Bond 123 Baker 867-5309
2222 Mark Jones 450 21st Ave 888-5411
What I would like to have returned is
storeNum, franchisee, item, type, vendorName, size, price, year
But only for the most recent year.
5555, David Smith, Mashed Potatoes, Side, Acme Foods, Large, 3.99, 2015
3333, James Bond, Mashed Potatoes, Side, Smith's Wholesale, 3.69, 2014
2222, Mark Jones, Mashed Potatoes, Side, Acme Foods, Large, 3.89, 2014
I hope that made sense, I'm at a complete loss of how to join the multiple tables and only pulling data for the most recent year.
Thanks,
Kevin
I have this working but have run into another issue where I may have multiple prices for a given year due to a mid-year price increase. How can I go about adding an additional sub-query to grab the max price after I've selected the max year?
My current query
SELECT m.storeNum, m.itemNum,size,m.price,year FROM ItemMenu m,
(SELECT storeNum, itemNum, MAX(year) maxYear FROM ItemMenu
GROUP BY storeNum, itemNum) yt, (SELECT storeNum, itemNum, MAX(price)
maxPrice FROM ItemMenu) mp
WHERE m.storeNum=yt.storeNum AND m.itemNum=yt.itemNum
AND m.year=yt.maxYear AND m.itemNum=5000 AND m.storeNum=205706;
Returns valid results for max year (I've selected a specific store and item to reduce the number of results).
+----------+---------+------------+-------+------+
| storeNum | itemNum | size | price | year |
+----------+---------+------------+-------+------+
| 205706 | 5000 | Individual | 1.59 | 2014 |
| 205706 | 5000 | Large | 3.69 | 2014 |
| 205706 | 5000 | Large | 3.59 | 2014 |
| 205706 | 5000 | Individual | 1.79 | 2014 |
+----------+---------+------------+-------+------+
I need to further reduce this so I only get the values of $1.79 and 3.69.
Thanks
-Kevin
You'll need to use a subquery: 1st get a set of the most recent year for a given (item,store) pairing. Next, select the price for that (item,store,year) triplet:
SELECT m.storeNum, m.itemNum,price,year FROM ItemMenu m,
(SELECT storeNum, itemNum, MAX(year) maxYear FROM ItemMenu
GROUP BY storeNum, itemNum) yt
WHERE m.storeNum=yt.storeNum AND m.itemNum=yt.itemNum
AND m.year=yt.maxYear;
You can, of course, join the various ID->name tables onto this to get the human-readable data, but I suspect your issue was figuring out how to get the most recent prices.
It should be also noted that this could be done with a JOIN rather than including the subquery in the FROM section; that may be faster.

Access Crosstab subtotal columns

I have a following question regarding crosstabs in Access:
How do I create a subtotal columns?
What I want to see as a result of the query is this:
Nov 2010 Dec 2010 2010 Total Jan 2011 Feb 2011
Row1 2 4 17 3 2
Row2 8 6 35 7 5
How do I create these subtotals for the year? (It's ok, if the year data will be in the end, after all months)
The problem is that I need to do this without hardcoding each year, the query should work with any dataset
Thanks in advance!
Say we have raw [SalesData]
SalesYear SalesMonth Region SalesTotal
--------- ---------- ------ ----------
2010 11 East 45
2010 11 West 58
2010 12 East 55
2010 12 West 63
2011 1 East 51
2011 1 West 54
2011 2 East 55
2011 2 West 61
We can create a [SalesTotals] query to combine the monthly sales totals with the yearly totals...
SELECT SalesYear & "-" & Format(SalesMonth, "00") AS SalesPeriod, Region, SalesTotal FROM SalesData
UNION ALL
SELECT SalesYear & "-Total", Region, SUM(SalesTotal) FROM SalesData GROUP BY SalesYear, Region;
...which produces
SalesPeriod Region SalesTotal
----------- ------ ----------
2010-11 East 45
2010-11 West 58
2010-12 East 55
2010-12 West 63
2011-01 East 51
2011-01 West 54
2011-02 East 55
2011-02 West 61
2010-Total East 100
2010-Total West 121
2011-Total East 106
2011-Total West 115
Then we can do our crosstab query on the [SalesTotals] query...
TRANSFORM Sum(SalesTotals.[SalesTotal]) AS SumOfSalesTotal
SELECT SalesTotals.[Region]
FROM SalesTotals
GROUP BY SalesTotals.[Region]
PIVOT SalesTotals.[SalesPeriod];
...which produces
Region 2010-11 2010-12 2010-Total 2011-01 2011-02 2011-Total
------ ------- ------- ---------- ------- ------- ----------
East 45 55 100 51 55 106
West 58 63 121 54 61 115

MySQL query for grouping data

can anyone please guide me with writing MySQL query for following scenario.
The data in table is like this,
Table Name: user
user_id country city age
----------------------------------------------
1 India Mumbai 22
2 India Mumbai 22
3 India Delhi 22
4 India Delhi 23
5 India Chennai 23
6 China Beijing 20
7 China Beijing 20
8 China Shanghai 20
9 USA New York 30
10 USA New York 30
11 USA New York 30
12 USA Los Angeles 31
13 USA Los Angeles 31
14 USA Los Angeles 40
I want result to be like this which is basically sum of all users in particular country's city having same age.
country city age age_count
----------------------------------------------
India Mumbai 22 2
India Delhi 22 1
India Delhi 23 1
India Chennai 23 1
China Beijing 20 2
China Shanghai 20 1
USA New York 30 3
USA Los Angeles 31 2
USA Los Angeles 40 1
Try this :;
SELECT country,
city,
age,
count(user_id) AS age_count
FROM user
GROUP BY country,
city,
round(age)
select country, city, age, count(*) age_count
from user
group by country, city, age