sql >> Database >  >> RDS >> Sqlserver

Afstandsberekening met enorme SQL Server-database

Je zou erger kunnen doen dan kijken naar de GEOGRAPHY gegevenstype, bijvoorbeeld:

CREATE TABLE Places
(
    SeqID       INT IDENTITY(1,1),
    Place       NVARCHAR(20),
    Location    GEOGRAPHY
)
GO
INSERT INTO Places (Place, Location) VALUES ('Coventry', geography::Point(52.4167, -1.55, 4326))
INSERT INTO Places (Place, Location) VALUES ('Sheffield', geography::Point(53.3667, -1.5, 4326))
INSERT INTO Places (Place, Location) VALUES ('Penzance', geography::Point(50.1214, -5.5347, 4326))
INSERT INTO Places (Place, Location) VALUES ('Brentwood', geography::Point(52.6208, 0.3033, 4326))
INSERT INTO Places (Place, Location) VALUES ('Inverness', geography::Point(57.4760, -4.2254, 4326))
GO
SELECT p1.Place, p2.place, p1.location.STDistance(p2.location) / 1000 AS DistanceInKilometres
    FROM Places p1
    CROSS JOIN Places p2
GO  
SELECT p1.Place, p2.place, p1.location.STDistance(p2.location) / 1000 AS DistanceInKilometres
    FROM Places p1
        INNER JOIN Places p2 ON p1.SeqID > p2.SeqID
GO  

geography::Point neemt de breedte- en lengtegraad op, evenals een SRID (Special Reference ID-nummer). In dit geval is de SRID 4326, wat de standaard lengte- en breedtegraad is. Omdat je al breedte- en lengtegraad hebt, kun je gewoon ALTER TABLE om de kolom geografie toe te voegen en vervolgens UPDATE om het te vullen.

Ik heb twee manieren laten zien om de gegevens uit de tabel te halen, maar je kunt hiermee geen geïndexeerde weergave maken (geïndexeerde weergaven kunnen geen self-joins hebben). U kunt echter een secundaire tabel maken die in feite een cache is, die op basis van het bovenstaande wordt gevuld. U hoeft zich dan alleen maar zorgen te maken over het onderhoud ervan (kan worden gedaan via triggers of een ander proces).

Merk op dat de cross join u 250.000.000.000 rijen zal opleveren, maar zoeken is eenvoudig omdat u alleen naar een van de kolommen van de plaats hoeft te kijken (d.w.z. SELECT * FROM table WHERE Place1 = 'Sheffield' AND distance < 100 , de tweede geeft u aanzienlijk minder rijen, maar de zoekopdracht moet dan rekening houden met zowel de kolom Plaats1 als Plaats2).




  1. Meerdere select-instructies in Enkele query

  2. HTML-formulieren invullen met mysql-gegevens met behulp van php coming up null

  3. Bestandspad opslaan naar Database / SQL

  4. Hoe mysql-rijen met dezelfde kolomwaarde in één rij te groeperen?