我正在尝试让SQL Server为每个LocationID生成每个Zip代码的随机点。所以我为每个邮政编码添加了中心点,并希望在中心点周围分配这些点。对于每个locationID,我想要一个观点。这是我目前的表格。
表名=位置
LocationName; varchar
locationID; int
ZIP: int
CentroidLat;float
CentroidLng;float
示例数据:
LocationName LocationID Zip CentriodLat CentroidLNG
-------------------------------------------------------------------------
JV 1 99999 38.999999 - 93.999999
JV 2 99999 38.999999 - 93.999999
AA 1 11111 37.999999 - 94.999999
AA 2 11111 37.999999 - 94.999999
AA 3 11111 37.999999 - 94.999999
BB 1 22222 36.999999 - 95.999999
BB 2 22222 36.999999 - 95.999999
因此,对于每个zip的LocationId,我想在邮政编码中使用随机lat。我可以在方形或圆形中得到这个可以正常工作。它不需要太精确。此外,每个邮政编码将是一个不同的大小,所以如果有一个变量,我可以在代码中手动更改,这将是伟大的!
这就是我想要的样子
`LocationName LocationID Zip CentroidLat Centroid RandLat RandLNG`
JV 1 99999 38.999999 - 93.999999 -93.7436 -94.0124
JV 2 99999 38.999999 - 93.999999 -93.9653 -94.0052
AA 1 11111 37.999999 - 94.999999 110.9636 -95.7219
AA 2 11111 37.999999 - 94.999999 102.6538 -95.7489
AA 3 11111 37.999999 - 94.999999 101.9887 -96.0089
BB 1 22222 36.999999 - 95.999999 137.5311 -97.9698
BB 2 22222 36.999999 - 95.999999 46.7497 -96.9266
这可能吗?
我发现了这个...... SQL Server generating random spatial geography around point? 但无法让它发挥作用。
我一直收到这个错误:
Msg 116,Level 16,State 1,Line 18
当未使用EXISTS引入子查询时,只能在选择列表中指定一个表达式。
当我尝试将表名和列插入代码顶部时发生错误。
提前谢谢!
答案 0 :(得分:0)
您获得的错误是一般SQL错误,与空间/地理对象无关。在您的链接引用的代码中,我创建了一个表变量来保存一些示例值并进行设置,以便为邮政编码98765返回多个值。运行代码,您将得到您描述的错误:< / p>
DECLARE @geo AS GEOGRAPHY
, @newgeo AS GEOGRAPHY
DECLARE @ZipCodes AS TABLE
(
[ZipGeo] GEOGRAPHY
, [ZipCode] SYSNAME
);
INSERT INTO @ZipCodes
([ZipGeo]
, [ZipCode])
VALUES (geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656 )', 4326),N'98765'),
(geography::STGeomFromText('POLYGON((-122.358 47.653 , -122.348 47.649, -122.348 47.658, -122.358 47.658, -122.358 47.653))', 4326),N'98765');
SET @geo = (SELECT [ZipGeo]
FROM @ZipCodes
WHERE [ZipCode] = '98765')
解决这个问题的方法是“SELECT TOP(1).... ORDER BY ...”如下所示,但是ORDER BY在这里真的没有使用,你不能按GEOGRAPHY类型排序。
DECLARE @geo AS GEOGRAPHY
, @newgeo AS GEOGRAPHY
DECLARE @ZipCodes AS TABLE
(
[ZipGeo] GEOGRAPHY
, [ZipCode] SYSNAME
);
INSERT INTO @ZipCodes
([ZipGeo]
, [ZipCode])
VALUES (geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656 )', 4326),N'98765'),
(geography::STGeomFromText('POLYGON((-122.358 47.653 , -122.348 47.649, -122.348 47.658, -122.358 47.658, -122.358 47.653))', 4326),N'98765');
SET @geo = (SELECT TOP(1) [ZipGeo]
FROM @ZipCodes
WHERE [ZipCode] = '98765'
ORDER BY [ZipCode])
或者你可以这样做,但这是非常糟糕的做法。
DECLARE @geo AS GEOGRAPHY
, @newgeo AS GEOGRAPHY
DECLARE @ZipCodes AS TABLE
(
[ZipGeo] GEOGRAPHY
, [ZipCode] SYSNAME
);
INSERT INTO @ZipCodes
([ZipGeo]
, [ZipCode])
VALUES (geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656 )', 4326),N'98765'),
(geography::STGeomFromText('POLYGON((-122.358 47.653 , -122.348 47.649, -122.348 47.658, -122.358 47.658, -122.358 47.653))', 4326),N'98765');
SELECT @geo = [ZipGeo]
FROM @ZipCodes
WHERE [ZipCode] = '98765';
最好有一个可以订购的列,只返回该集的顶部(1)。这样你的SQL语句就是确定性的。由于SQL不保证订单,您必须订购结果以保证退货。
无论如何,这是您所看到的错误的原因。有几种方法可以解决它。这是我在生产代码中看到的常见错误,人们认为数据总是“好”并且只返回一个值。然后,当数据返回多个值时(如您的情况或我的示例),代码失败,人们想知道为什么。
最佳做法是以防御性和装饰性的方式编写代码,以便准确说明您希望得到的内容。