MySQL Multiple query with a bit of logic - mysql

I have a Users table with these values (stripped down for the example):
Name
City
County
StateProvince
Country
Continent
Strength
Endurance
Intelligence
I basically want a query that returns the highest stat by region for yourself. If you have the highest Strength (67) in the country, highest Endurance (59) in your City, and not the highest Intelligence anywhere, I'd like a 2 row result of:
('Strength', 67, 'Country', 'United States')
('Endurance', 59, 'City', 'Redmond')
Note that if you have the highest Strength in the country, you will also have the highest strength in the state/province, county, and city (but I'd like those not to be returned in the result). I can do this all using multiple SELECT queries, however, I'd like to know how to do this in one single query for efficiency (or if that's even a good idea?). I'd imagine the logic would go something like (pseudo code):
(SELECT FROM Users ORDERBY Strength WHERE Country = 'MyCountry' LIMIT 1) IF Name != 'Me' (SELECT FROM Users ORDERBY Strength WHERE StateProvince = 'MyState' LIMIT 1) ... and so on
Furthermore, the above would also need to work with Endurance and Intelligence. Thanks!

Check this link MySQL control-flow-functions
SELECT CASE 1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'more' END;

Related

How can I use a subquery on my query results and then ORDER BY a calculated result for each row?

Context
I'm having some trouble putting together the logic of subqueries(?) together in my head.
*---------*---------*---------*------------*------------*---------*
|GUEST_ID | Country | County | Attending | Donation | Party |
*---------*---------*---------*------------*------------*---------*
I have a database containing records about attendees of an charity ball.
GUEST_ID: Table key.
Country: Country the guest is from.
County: County the guest is from (i.e. a region within that country).
Attending: Whether or not the guest is attending (i.e. true or false).
Donation: Amount the guest is donating to the cause.
Party: Which Party the guest is attending.
Goal
I wish to display a table broken down by Country and County, showing the number of attendees from each Country + County, and the average donation of those who are attending from that Country + Country. I'd then like to order the rows from highest average donation to lowest. I understand the constituent parts of this query, however I'm not sure how to 'glue' it together as a whole.
I can GROUP BY Country, County.
I can SUM(Donation).
I can COUNT(*) WHERE ATTENDING = 'Yes'
And I know I can SET #variables to store results in the interim.
I also know I can ORDER BY DESC.
So far
My issue is with understanding how to combine these elements into a functioning query. I'm guessing I need to use subqueries however it's getting the order right I'm having trouble with. This is what I have so far -
SELECT SUM(`Donation`) AS `TotalDonations`, `Country`, `County`
FROM `GuestList`
WHERE `Party` = `2014CharityBall`
GROUP BY `Country`, `County`
I'm not sure how to add the subquery to find the COUNT of only those guests who are definitely attending, or how to calculate the TotalDonations / DefinitelyAttending and then ORDER BY this.
Results Required
*------------*------------*---------------*---------------*---------------*
| Country | County | # of Attendees|Total Donations|Avg. Donation |
*------------*------------*---------------*---------------*---------------*
Country: Country the guests are from.
County: County the guests are from (i.e. a region within that country).
# of Attendees: Number of attendees (Attending = 'true') within that country and county.
Total Donations: Total donations of all those attending (Attending = 'true') within that country and county (e.g. SUM(Donation)).
Avg. Donation: Average donation of all those attending (Attending = 'true') within that country and county (e.g. AVG(Donation) - that is, ofc, Total Donations / # of Attendees).
Extra Credit
Just an expression ;)
If I want to calculate the Total Donations among all donators invited to the party, and, separately, the Total Donations solely among those donators attending the party, how would I do that?
SELECT `Country`,
`County`,
SUM(`Donation`) AS `TotalDonations`,
FORMAT(AVG(`Donation`), 0) AS `AVGDonations`,
COUNT(1) Attending
FROM `GuestList`
WHERE `Party` = `2014CharityBall`
AND Attending = `Yes`
GROUP BY `Country`, `County`
Order by 4 desc

How to sort based on keyword first?

Here is a sample Database
First_name country
Andy US
Manu India
Paul Pakistan
Ramesh Pakistan
Rich India
So, what i want is to select all records from the above table and display according to name.
Like :-
I want to select person name to be display first whose country name is India and after US, Pakistan.
How can i perform this task in single SQL query ?
Update
I don't know how many Country are there.
Country the need to be display first will be input by the user.
Use a CASE statement to give each record a sortkey. 0 for a country match, 1 for a mismatch, so the desired country comes first.
select *
from mytable
order by case when country = #country then 0 else 1 end, first_name
May be something like this
Select * From Table1
Order By CASE WHEN country = 'INDIA' THEN 0
WHEN country = 'US' THEN 1
Esle 2
END;
Or You can use FIELD
Select * From Table1 Order By FIELD(country, 'India', 'US', 'Pakistan') ;
Use FIELD Function
Try this:
SELECT fitst_name, country
FROM tableA
ORDER BY FIELD(country, 'India', 'US', 'Pakistan'), fitst_name

MySQL Query to display records from table

I have a query.I have table with two columns country and state.I want to display columns in following format
Country State
----------- ---------
India Delhi
Bangalore
Kolkata
Mumbai
USA California
Florida
Las Vegas
Virginia
It means "India" just appear one time in country column and and repeated values would come as blank value in country column when i select country and state from table.
Thanks in advance
Presentation is usually if not always better done outside of SQL so I'd recommend doing this in whatever your presentation layer runs, but if it's a requirement for the query, you can do it using session variables;
SELECT Country, State FROM (
SELECT IF(Country=#country, '', Country) Country, State, #country := Country
FROM (SELECT Country, State FROM Table1 ORDER BY Country, State) dummy1,
(SELECT #country:='') dummy2
) dummy3;
An SQLfiddle to test with.
Just to show a (probably) better way, you can use this to get a list of states per country, and process it further in your presentation layer;
SELECT Country, GROUP_CONCAT(State) FROM Table1 GROUP BY Country;
Another SQLfiddle.
use pl/sql.Moreover your table would be voilating 5th normal form.

SQL Query to provide me with the total number

I have a table with 3 columns
Column 0: auto inc index
Column 1: Person's Gener
Column 2: The STATE the person lives in (US States and Puerto Rico)
I want to run a query that tells me how many MEN are in each state
so the output would list all 50 states (in 1 column) and the second would be a number to determine the number of MEN in that state
Alaska 1000
New York 85000
(the figures above aren't accurate but i'm illustrating what I am looking for)
Thanks
You need to use a GROUP BY clause and the COUNT aggregate function.
SELECT State, COUNT(*) AS NumberOfMen
FROM your_table
WHERE Gender = 'M'
GROUP BY State
try this
select STATE, count(*) as num from table_name where gender ='MALE' GROUP BY STATE;

How to prioritize a LIKE query select based on string position in field?

I am attempting to query a table for a limited resultset in order to populate an autocomplete field in javascript. I am, therefore, using a LIKE operator with the partial string entered.
If I have, for example, a table such as:
tblPlaces
id country
1 Balanca
2 Cameroon
3 Canada
4 Cape Verde
5 Denmark
For the sake of this example, let's say I want two rows returning - and yeah, for this example, I made up a country there ;) I want to prioritize any instance where a partial string is matched at the beginning of country. The query I began using, therefore is:
SELECT id, country FROM tblPlaces WHERE country LIKE 'ca%' LIMIT 2
This returned 'Cameroon' and 'Canada' as expected. However, in instances where there are no two names in which the string is matched at the beginning of a word (such as 'de'), I want it to look elsewhere in the word. So I revised the query to become
SELECT id, country FROM tblPlaces WHERE country LIKE '%ca%' LIMIT 2
This then returned 'Cape Verde' and 'Denmark', but in doing so broke my original search for 'ca', which now returns 'Balanca' and 'Cameroon'.
So, my question is, how to go about this using a single query that will prioritize a match at the start of a word (perhaps I need to use REGEXP?) I am assuming also that if the 'country' column is indexed, these matches will at least be returned with subsequent alphabetical priority (i.e. Cameroon before Canada etc).
If you mean to prioritize matches that are Exactly at the start...
SELECT id, country
FROM tblPlaces
WHERE country LIKE '%ca%'
ORDER BY CASE WHEN country LIKE 'ca%' THEN 0 ELSE 1 END, country
LIMIT 2
EDIT
More generic and possibly faster (Assuming "closer to the start the 'better' the match")...
SELECT id, country
FROM tblPlaces
WHERE country LIKE '%ca%'
ORDER BY INSTR(country, 'ca'), country
LIMIT 2