MYSQL Postcode lookup - mysql

I have a MYSQL table with the following fields postcode, town, county. Based on the postcode number I want to do a lookup to get the closest matching town and county.
The postcodes are essentially postcode districts, so for example:
AL1 = Saint Albans, Hertfordshire
AL10 = Hatfield, Hertfordshire
In the example above lets say I'm querying AL10 I want to retrieve the closest match, so in this case it would be AL10 = Hatfield, Hertfordshire. But if AL10 didn't exist I want to retrieve AL1.
I have got around this by first querying for a match on AL10 then if that failed AL1, then if that failed AL.
But this seems like a very inefficient way to achieve this seeing as I'm querying the table potentially 3 times. Is there a better and more efficient way to achieve the same goal?

Related

Query to find lakes that are in multiple states

I have tables to hold information about Lakes, Counties, and States. I also have a table called LakeLocation that is simple a pair of foreign keys of a LakeID and CountyID, so I can know where they are. And each county has a StateName inside it.
A high-level view of it all is something like this:
Lake = {id,name,...}
County = {id, name, StateName ....}
State = {name, ...}
LakeLocation = {LakeID, CountyID}
I am trying to find out which states have lakes that are in more than one state. An example is Lake Tahoe which crosses four county lines and two state lines. I know that I will need a recursive query, but I only understand those for simple one table child/parent type relationships. Not this.
How can I design a query that does what I need? Thanks
You only need a group by to know what are the lakes
SELECT LakeID
FROM LakeLocation
GROUP BY LakeID
HAVING COUNT(CountyID) > 1
Then if you want lake names
SELECT *
FROM Lake
WHERE LakeID IN (<previous query>)

MySql total is bigger than individual elements

I have a huge MySql table that is in use in production. I have tables which are named by geographical areas with foreign keys for smaller divisions. It is structured like db_country-> tbl_city1, tbl_city2, tbl_city3 and each tbl_city has rows for households inside with other details like street, address and number of people for each household.
PROBLEM: If I pull the data for each family grouped by STREETS I get the correct number of people but when I call the number of people in the entire city, I get a slightly inflated number. I know there must be something I've messed up, what is the possible fail area in this scenario?
The first query that yields inflated output is:
SELECT sum(people) AS people FROM city WHERE division=2136 AND status=1;
and the second query that yields correct output is:
SELECT street.name, SUM(people) AS people FROM city INNER JOIN streets
ON city.street=streets.id WHERE division=2136 AND status=1
GROUP BY street.name;
The picture is the real output, above table shows combined total(inflated) while the lower one shows individual streets/villages with the correct number MYSQL OUTPUT IMAGE
There are records in city table which have no related street record matching the join city.street=streets.id.
Try this sql to find out the missed records.
Select city.* from city left join street on city.street=streets.id
WHERE division=2136 AND status=1 where street.id is null.

Count and distinct in mysql (comma separated data in table)

I am trying to get the details from mysql database.
My table have location field.
Data is like below
Location
India
UK,Finland, India
USA, NZ, AUS, Spain
I am trying to get the count for each location.
select count(distinct location) from posting
This is the query i have written at the moment for testing purpose. It return me count.
I want to get the details like below.
India -2
UK - 1
Finland -1
USA - 1
Something like that.
Note Please ignore dash as this is just to show you what i want.
Please advise me as i am not good in database.
You should not be storing multiple values in a single columns. Delimited strings are not the right way to store values in SQL. The proper way is a junction table.
If I assume that you have a list of locations, then you can do:
select l.location, count(*)
from location l join
posting p
on find_in_set(l.location, p.location) > 0;
If you don't have such a table, I would recommend that you focus on fixing your data structure first, rather than trying to get such a query to work.
SELECT COUNT(location),location FROM posting;
Try this one out. It will give you a similar output.

Update table based on other 2 related tables

I have a strange problem. I got some data for cities, regions and countries in CSV format and imported them into MySQL tables.
I have 3 tables and their fields
1. City : id, name, country_code, region_number
2. Region : region_number, country_code, name
3. Country : country_code, name
Now things get a little complicated, as I added an auto-generated id column to the region table, so the region x for country y would be unique.
The thing is: Now i am trying to update city field region_number to hold this unique value (the new id column in region) so I can have relations city->region.
The relation region->country or country->region is OK.
Is it possible to write an update query that would update city region_code (or fill some new column, eg. region_id) with correct values?
If not an query, what could I use to get the correct values into the cities table?
I have arround 3 million records!
If I understant correctly, I think you are looking for something like this:
UPDATE
City inner join Region
on City.country_code = Region.country_code
and City.region_number = Region.region_number
SET
City.new_column = Region.id
However, since there's a relation already between City and Region, I am not sure this is the right thing to do, since it will make the table not normalized.
Now i am trying to update city field region_number to not hold this unique value
The only way you can do this is if the region_number uniquely identifies each region - and if that's already the case then you are wasting your time by creating redundant references. Although frankly, if these really are your table structures, there's no reason for using surrogate keys. And if there's no reason for using surrogate keys then the region and country table are redundant.

Displaying name from ID of lookup tables - design Q

I am sure this is a basic question but I am new to SQL so anyways, for my user profile I want to display this: location = "Hollywood, CA - USA" if a user lives in Hollywood. So I assume in the user table there will be 1 column like current_city which will have ID say 1232 which is a FK to the city table where city_name for this PK = Hollywood. Then connect with the state table and the country table to find the names CA and USA as the city lookup table will only store the IDs (like CA = 21 and USA = 345)
Is this the best way to design the table OR I was thinking should I add 2 columns like city_id and city_name to the user_table. And also add country_id, country_name, state_id, state_name to the city table. This way i save on trips to other parent tables just to fetch the name for the IDs.
This is only a sample use case but I have lots of lookup ID tables so I will apply the same principle to all tables once i know how to do it best. My requirement is scalability and performance so whatever works best for these is what i would like.
The first way you described is almost always better.
Having both the city_id and city_name (or any pair of that kind) in the users table is not best practice since it may cause data discrepancies - a wrong update may result in a city_id that does not match the city_name and then the system behavior becomes unexpected.
As said, your first suggestion would be the common and usually the best way to do this. If table keys are designed properly so all select statements can use them efficiently this would also give the best performance.
For example, having just the city_name in the users table would make it a little quicker to find and show the city for one user, but when trying to run other queries - like finding all users in city X, that would make much less sense.
You can find a nice series of articles for beginners about DB normalization here:
http://databases.about.com/od/specificproducts/a/2nf.htm. This article has an example which is very much like what you are trying to achieve, and the related articles will probably help you design many other tables in your DB.
Good luck!