MS Access -- Using Order By in a Union Query - ms-access

I have a need for a query that will select the CountryName from a table named Country such that the "United States" always comes out on top, and all the remaining countries follow in Alphabetical order. I used the following code, the intent of which is to select only the United States, and then use the Union to add all other countries after the United States in alphabetical order. It seemed to work, but I then noticed that when a few additional countries were added to the table, the United States was on top as desired, but the added countries were just appended to the query results (that is, not in alphabetical order as desired). Any thoughts? I'm not sure if what I want is even possible in Access. "I'm using Access version with Office 360.)
SELECT * from
(
SELECT Country.CountryDesc FROM Country where (((Country.CountryDesc)="united states"))
) dummy_alias1
UNION ALL SELECT * from
(
SELECT Country.CountryDesc FROM Country WHERE (((Country.CountryDesc)<>"united states"))
ORDER BY Country.CountryDesc
) dummy_alias2;

As you noticed, UNION ignores ORDER BY of subqueries. However, don't need a UNION query. Calculate a value to base sorting on:
SELECT Country.*
FROM Country
ORDER BY IIf(CountryDesc = "United States", 1, 2), CountryDesc;

Related

How do I get distinct value in one row and their respective average values as output in mySQL

I have a mySQL table with 100 rows and 6 columns namely ; full_name, name, score, city, gender, rating. I want the output as one column containing distinct city values (there are only 5 distinct cities initially & the user input value of his/her city will be added, namely; Delhi, Mumbai, Patna, Chennai ,Pune) and the second column having their respective avg score.
The database is linked to the python code which I am working on & use takes input which is stored in the above 6 columns. Then according to the user request, the output as analysis is showed as graphs using matplotlib. But I am really stuck at this part where I need to show a graph having X-VALUES as city names and Y-VALUES as respective avg score for that, I need to know the query to get such an output in mySQL where we get 2 columns storing the above.
How do I do it ?
SELECT city AS X,AVG(score) AS Y
FROM yourtable GROUP BY city
Is this, what you ment? Or if you want the result as one row, you add GROUP_CONCAT:
SELECT GROUP_CONCAT(X) AS gX,GROUP_CONCAT(Y) AS gY FROM
(SELECT city AS X,AVG(score) AS Y
FROM yourtable GROUP BY city) g
ok, redbull helps...
correct syntax :
select city, avg(score) from data group by city;
wrong syntax (what I was trying to do earlier) :
select data.distinct(city), data.avg(score) , check.check_city from data, (select name, distinct(city) as check_city from data) check where data.name = check.name and data.city in check.check_city;
Thanks Anyway !

Get data from table by County in a single row

I want to get data from table in a single row for single county. Right now as shown in images it shows Different rows for Single county as Kalamazoo. It should show single with both records in single row.
I am using following query
SELECT County, Virus, SumOfPositiveTests
FROM StatewiseData
WHERE State = 'MICHIGAN'
I want the results to be shown as following
County Virus SUMOFPOSITIVETESTS
---------------------------------------------
Kalamazoo H3N2,H3N8 3
Total sum of both H3N2 and H3N8
use MYSQL GROUP_CONCAT
The following MySQL statement will return a list of comma(,) separated 'Virus's for each group of 'County' from the StatewiseData table
SELECT County,GROUP_CONCAT(Virus),sum(SumOfPositiveTests) FROM StatewiseData where State='MICHIGAN' group by County
Try this if you are using mysql:
SELECT country, GROUP_CONCAT(virus) _virus, SUM(SumofPositiveTests) as TotalPostitiveTest
FROM StatewiseData
WHERE Country = 'Kalamzoo'
GROUP BY Country
Please mind that this will not work with most databases, as they need you to to specify only the grouping field and aggregate functions of other fields in your query.
Here is the source
Try this. this would work on IBM DB2 and MySQL. what DB you are using
SELECT DISTINCT Country, Virus,SumOfPositiveTests FROM Customers where State='MICHIGAN' group by Country;
why are you using state in where condition? (please provide list of columns do you have in a column if i missed something)
if you are only selecting the country then it should be as simple as:
SELECT County,Virus,SumOfPositiveTests FROM StatewiseData where Country='Kalamzoo'
if you want to select summary or totals of single country then you you should use sum like:
SELECT country, SUM(SumofPositiveTests) as TotalPostitiveTest
FROM StatewiseData WHERE Country='Kalamzoo' GROUP BY Country

ALL sql with subquery, and NOT exist

Im doing a sql problem and the question is this:
Get all the ship's classes of Russia. If there are no classes of Russia in the database, get all the classes in the database.
Result set: country, class
3 answers (#3 is wrong):
select country, class from Classes
where country = ALL(select country from Classes
where country='Russia')
select country, class
from classes
where not exists (select country
from classes
where country='Russia')
or country='Russia'
select distinct country, class
from classes
where country not in(select country
from classes
where country='Russia')
or country='Russia'
Can anyone explain how the "ALL example works", I dont fully understand how this covers all the cases above: finding only russian classes and if none all the others.
Can anoyone also explain how ans2 and wrong ans3 is different, I think it might have something to do with null values but im not too sure..im quite new to sql
The all is a comparison to all values in the subquery and I don't think the way you are using it is very useful.
It would be much more useful for a numerical comparison like greater than, less than, etc.
From the MySQL site:
SELECT s1 FROM t1 WHERE s1 > ALL (SELECT s1 FROM t2);
This would select all the s1's from t1 that are greater than all of the s1's from t2.
Your example
Your example: select country, class from Classes where country = ALL(select country from Classes where country='Russia') this subquery is only returning a bunch of rows of 'Russia' as you're only selecting country where country equals Russia.
However, ALL, as documented in Oracle (not documented in MySQL) will return a true condition if no values are present allowing you to select all from Russia unless no Russia rows exist.

Problems with CREATE VIEW

The question is to create a view called NumberOfCities_v. And then use the view to list
countries that have more than 20 cities in the descending order of number of cities.
This is my create a view statement:
CREATE VIEW NumberOfCities_v AS
SELECT
country.code as "Country Code",
country.name as Country,
count(countrycode) as "Number Of Cities"
FROM
city,
country
WHERE
city.countrycode = country.code
GROUP BY country.code, country.name
HAVING COUNT(countrycode) > 20
ORDER BY COUNT(countrycode) desc;
I don't get any records, but I think I've created the view. According to my powerpoint, I should be getting both. Apparently I have some field errors with that statement with I try to select the view with another statement. But When I use the exact statement without the create view, I get the results I need. Can someone explain why that is?
You need to fire sql query:
Select * from `NumberOfCities_v`
to get all the records generated in view.

mysql - need two limits?

Given a table containing awards earned over several years by members of an organization that consists of multiple geographic districts, what mysql query would show the top award earner in each district? I can easily get the top ten award earners across all districts with this query:
SELECT Membername, count(Award)as Number FROM awards
GROUP BY Membername
ORDER BY Number desc
LIMIT 10
But I need a list with the top earner for each district (there are about 90 of them), and I haven't gotten it right yet.
I tried this:
SELECT Membername, District, count(Award)as Number FROM awards
GROUP BY Membername, District
ORDER BY Number desc, District
LIMIT 90
It has accurate counts for the members, but isn't showing one per district, so some districts show up more than once. How do I get it to list the top earner per district, with each district showing up just once?
You'll have to do it by applying a "rank" per district, then only grab per rank = 1... The #LastDistrict at the join location is defaulted to zero, in case the district is based on an ID. If district is char based, you can just change it to = "" instead to match the data type.
To clarify what is happening. The "AwardCounts" pre query does the entire query per district and member with however many award counts. Then, ordered by district and member award count (descending), thus putting the highest award count at the first position per district.
That is joined to another bogus alias "SQLVars" which just creates inline variables to the query called #RankSeq and #LastDistrict. So, the first time in, the "DistRankSeq" will become a 1 for the first district, then prime the "#LastDistrict" with the value of the district. The next entry for the same district (since it will be in proper sequence order) will be assigned the rank of 2, then 3, etc... When there is a change from whatever the "LAST" District was to the new record being tested, the rank gets set back to 1 and starts over again. So you could have one district with 100 members, another with 5, another with 17...
So, your final query has all of them with their respective ranks... Now, apply the HAVING the final district rank = 1... Doing this, you could also adjust the having to get the top 3 members per district (for example)...
select
AwardCounts.District,
AwardCounts.MemberName,
AwardCounts.memberAwards,
#RankSeq := if( #LastDistrict = AwardCounts.District, #RankSeq +1, 1 ) DistRankSeq,
#LastDistrict := AwardCounts.District as ignoreIt
from
( select
a.district,
a.membername,
count(*) as memberAwards
from
Awards a
group by
a.district,
a.membername
order by
a.district,
memberAwards desc ) AwardCounts
JOIN (select #RankSeq := 0, #LastDistrict = 0 ) SQLVars
HAVING
DistRankSeq = 1
EDIT PER FEEDBACK
If its the aggregation thats taking the time, then I would do the following. Create a new table with nothing but the aggregations per district, name and initial rank for the district. As any new record is added to this table, the trigger then adds one to the aggregate table count, then checks where that person is within their district and re-updates its new rank position. You could take it a step further and have another table of just "TOP" member per district table that is one per district with the person's name. When a new person hits the top position, their name is put in the table, overwriting whoever was there last.
There's a fairly common way to do this, using self-joins. The trick is to replace a search for 'largest' with a search for 'those items with nothing bigger'. As you have already found out
SELECT Membername, District, count(Award) as Number FROM awards
GROUP BY Membername, District
returns you a nice result of award counts. Let's write ... to save a bit of space as shorthand for that.
Now consider
SELECT a.Membername, a.District, a.Number FROM (...) a LEFT JOIN (...) b
ON a.District=b.District
AND a.Number<b.Number
WHERE b.Membername IS NULL
where the ... is that stuff written above. It's basically saying, for every entry in the award counts (a), find me all the entries (b) in the same district with more awards, and only return (a) if there aren't any (b)'s... in other words, a is the champ.
You will need to finesse this a bit if there's more than one member in the same district with the same winning count... this query will return all the tied members. You'll have to decide how to handle that. And watch out for those districts that don't have any awards at all... they won't even appear in your table.
There's a page specifically dedicated to the problem - and if you look at the older manuals you'll see the max-concat trick - which is often still more efficient.