I have a table of postcodes and I want to update each postcode with its 3 nearest neighbours. Ie to fill in the blanks in this table:
postcode nearestPostco
I think you could do this with the pseudo-code:
REPLACE INTO table1 (postcode, nearestPostcode1, nearestPostcode2, nearestPostcode3)
SELECT "KY6 1DA", col1, col2, col3 FROM myTable WHERE ...;
it'd be easier to specify it seeing the real SQL.
Note the first column is specified as a constant in quotes. For this to work postcode
must be a UNIQUE
or PRIMARY
index.
Update Table1
Cross Join (
Select Min( Case When Z1.Num = 1 Then Z1.postcode End ) As PostCode1
, Min( Case When Z1.Num = 2 Then Z1.postcode End ) As PostCode2
, Min( Case When Z1.Num = 3 Then Z1.postcode End ) As PostCode3
From (
Select postcode
, @num := @num + 1 As Num
From postcodeTable
Where postcode = 'KY6 IDA'
Order By <equation to calculate distance> ASC
Limit 3
) As Z1
) As Z
Set nearestPostCode1 = Z.PostCode1
, nearestPostCode2 = Z.PostCode2
, nearestPostCode3 = Z.PostCode3
Where Table1.postcode = 'KY6 IDA'
Anytime I see a table with columns that have 1-up counters after their names, I get concerned.
In general, it is a Bad Idea (TM) to store data that can be calculated from data that is already stored. What happens if your application all of a sudden needs the 4 closest postal codes? What if the postal code boundaries change?
Assuming the distance calculation isn't very complex, you'll be better off in the long run not explicitly storing this data.
You can do something similar to this:
UPDATE table1
SET
nearestPostcode1 = pc1,
nearestPostcode2 = pc2,
nearestPostcode3 = pc3
FROM
(SELECT pc1, pc2, pc3 FROM ....) t
WHERE
postcode = 'KY6 1DA';
I found this related question on Stackoverflow on how to transform columns to rows:
MySQL - Rows to Columns
In your case, you can do something like
SELECT
IF(@rownum=1,postcode,'') ) AS pc1,
IF(@rownum=2,postcode,'') ) AS pc2,
IF(@rownum=3,postcode,'') ) AS pc2,
FROM
(SELECT postcode
FROM postcodeTable
ORDER BY <equation to calculate distance> ASC
LIMIT 3)
Here is a hack to simulate the ROW_NUMBER() functionality in MySQL [1]:
SELECT @rownum:=@rownum+1 rownum, t.*
FROM (SELECT @rownum:=0) r, mytable t;