Search code examples
sqlrswitch-statementms-access-2010

Assign Positions MS Access


I have a problem with MS Access (although I am a R programmer). I have one reference table containing Latitude(min, max) and Longitude(min, max) for each grid square. In MS Access I want to assign the correct grid square for each position of a second table using for example a query.

I solved the problem already in R, that's why I provide this example: I have a table containing Gridsquare positions.

data2 <- data.frame(
  GS= c('OOOZ','WYAG','WYAH','WZAG','WZAH','WZAJ','WZAK','WZAL','WZAM','WZAN','XAAG','XAAH','XAAJ','XAAK','XAAL','XAAM','XAAN','XAAP','XAAQ'),
                    Latitude= c(0,-47.633,-47.633,-47.883,-47.883,-47.883,-47.883,-47.883,-47.883,-47.883,-48.133,-48.133,-48.133,-48.133,-48.133,-48.133,-48.133,-48.133,-48.133),
                    Longitude= c(0,-60.75,-60.25,-60.75,-60.25,-59.75,-59.25,-58.75,-58.25,-57.75,-60.75,-60.25,-59.75,-59.25,-58.75,-58.25,-57.75,-57.25,-56.75)
                    )

And I have a second Table containing actual positions e.g.

Data <- data.frame(Latitude = rnorm(100, -50, 3), Longitude = rnorm(100, -60, 3))

In R, I would use something like this: (putting together first the Lat and then the Lon part)

GS_Lat <-function(Latitude){
case_when(
  Latitude <= -47.00 & Latitude > -47.25 ~ "WW",
  Latitude <= -47.25 & Latitude > -47.50 ~ "WX",
  Latitude <= -47.50 & Latitude > -47.75 ~ "WY",
  Latitude <= -47.75 & Latitude > -48.00 ~ "WZ",
  Latitude <= -48.00 & Latitude > -48.25 ~ "XA",
  TRUE ~ "OZ")`

And

GS_Lon <-function(Longitude){
  case_when(
  Longitude >= -64.00 & Longitude < -63.50 ~ "AA",
  Longitude >= -63.50 & Longitude < -63.00 ~ "AB",
  Longitude >= -63.00 & Longitude < -62.50 ~ "AC",
  Longitude >= -62.50 & Longitude < -62.00 ~ "AD",
  Longitude >= -62.00 & Longitude < -61.50 ~ "AE",
  Longitude >= -61.50 & Longitude < -61.00 ~ "AF",
  Longitude >= -61.00 & Longitude < -60.50 ~ "AG",
  Longitude >= -60.50 & Longitude < -60.00 ~ "AH",
  Longitude >= -60.00 & Longitude < -59.50 ~ "AJ",
  Longitude >= -59.50 & Longitude < -59.00 ~ "AK",
  Longitude >= -59.00 & Longitude < -58.50 ~ "AL",
  Longitude >= -58.50 & Longitude < -58.00 ~ "AM",
  Longitude >= -58.00 & Longitude < -57.50 ~ "AN",
  Longitude >= -57.50 & Longitude < -57.00 ~ "AP",
  Longitude >= -57.00 & Longitude < -56.50 ~ "AQ",
  TRUE ~ "OZ")

And then put them together with paste(GS_Lat(Data$Latitude), GS_Long(Data$Longitude))

In MS Access I tried to build an expression within a query, for example with switch

Longitude:=Switch([Longitude]<-63.5,"AA",[Longitude]<-63,"AB",[Longitude]<-62.5,"AC",[Longitude]<-62,"AD",[Longitude]<-61.5,"A",[Longitude]<-61,"A",[Longitude]<-60.5,"AG",[Longitude]<-60,"AH",[Longitude]<-59.5,"AJ",[Longitude]<-59,"AK",[Longitude]<-58.5,"AL",[Longitude]<-58,"AM",[Longitude]<-57.5,"AN",[Longitude]<-57,"AP",[Longitude]<-56.5,"AQ")

But the problem is, that the expression seem to complicated to compute for MS Access. Is there another way, to create a query column assigning the correct gridsquare for each position?

I really wouldn't know how to use SQL for this, maybe something like

SELECT P.*, 
  CASE
    WHEN P.Latitude <= -47.00 AND P.Latitude > -47.25 THEN 'WW'
    WHEN P.Latitude <= -47.25 AND P.Latitude > -47.50 THEN 'WX'
    WHEN P.Latitude <= -47.50 AND P.Latitude > -47.75 THEN 'WY'
    ...
    ELSE 'OZ'
  END AS Gridsquare
FROM Positions P
JOIN Gridsquares G ON P.Position = G.Position;

EDIT: That was my Query Design in the end Query Design

And I modified to code thanks to your answers to:

SELECT Positions.Latitude, Northing.Grid, Easting.Grid, Positions.Longitude
FROM (Positions INNER JOIN Northing ON (Positions.Latitude < Northing.To) AND (Positions.Latitude >= Northing.From)) INNER JOIN Easting ON (Positions.Longitude < Easting.To) AND (Positions.Longitude >= Easting.From);

Solution

  • When using a database, I'd rather put the configuration into tables. Then you can simply use JOIN to get the desired config value (grid).

    Example for latitude: GridLat
    Note that you need to cover both edge cases.

    LatID LatMin LatMax LatGrid
    1 -47,00 0,00 OZ
    2 -47,25 -47,00 WW
    3 -47,50 -47,25 WX
    4 -47,75 -47,50 WY
    5 -48,00 -47,75 WZ
    6 -48,25 -48,00 XA
    7 -90,00 -48,25 OZ

    Testdata: Position

    PosID Latitude
    1 -47,50
    2 -47,49
    3 -50,00
    4 -20,00

    SQL with JOIN:

    SELECT P.PosID, P.Latitude, GL.LatGrid
    FROM Position AS P 
    INNER JOIN 
    GridLat AS GL ON P.Latitude > GL.LatMin AND P.Latitude <= GL.LatMax
    

    Result:

    PosID Latitude LatGrid
    1 -47,50 WY
    2 -47,49 WX
    3 -50,00 OZ
    4 -20,00 OZ