SQL: 无法在复杂查询中将 nvarchar 转换为数字
SQL: Cannot convert nvarchar to numeric in complex query
我需要在我的数据库中从当前用户位置获取最近的机场 table。我找到了这个公式:https://de.scribd.com/presentation/2569355/Geo-Distance-Search-with-MySQL#page=7
所以上面link中描述的公式和我现在的情况有一些不同:示例在MySQL,我使用的是MS SQL(不是一个问题,我猜)。 lat
和 lon
被认为是具有 numeric
数据类型的数据库列,但由于某种原因,数据库 table 是用两个对应的 varchar
类型列创建的.
我的问题是:当我想使用 ORDER BY
子句时,它会抛出 Error converting data type nvarchar to numeric
,没有它,它会起作用。我对哪些垃圾作为字符串插入并迁移了它进行了一些研究,以便我只有一些空值。
我不能全部拿走,因为我只需要一个。但是,如果我在没有 ORDER BY
的情况下执行 TOP 1
,我不会得到 任何 机场而不是最近的机场。有谁知道如何修复查询?
提前致谢!
SELECT TOP 1
temp.Distance
FROM (
SELECT
(
3956 * 2 * ASIN(
SQRT(
POWER(
SIN((53.6349994 - abs(CAST(latitude_deg AS numeric))) * pi() / 180 / 2), 2) + COS(53.6349994 * pi()/180) * COS(abs(CAST(latitude_deg AS numeric)) * pi()/180) * POWER(SIN((10.0117336 - CAST(longitude_deg AS numeric)) * pi()/180 / 2), 2) ))) AS Distance
FROM Airport_Airports
WHERE
isnumeric(longitude_deg) = 1 AND isnumeric(latitude_deg) = 1 AND
longitude_deg LIKE '%[^0-9.]%' AND latitude_deg LIKE '%[^0-9.]%'
) AS temp
WHERE
temp.Distance < 50000
Order BY
temp.Distance
首先,这个逻辑说不通:
WHERE isnumeric(longitude_deg) = 1 AND
isnumeric(latitude_deg) = 1 AND
longitude_deg LIKE '%[^0-9.]%' AND
latitude_deg LIKE '%[^0-9.]%'
like
正在寻找 非数字 字符。我想你打算:
WHERE isnumeric(longitude_deg) = 1 AND
isnumeric(latitude_deg) = 1 AND
longitude_deg NOT LIKE '%[^0-9.]%' AND
latitude_deg NOT LIKE '%[^0-9.]%'
这确保值是数字。
您的问题的解决方案——至少在 SQL Server 2012+ 中——是使用 try_convert()
或 try_cast()
:
(3956 * 2 * ASIN(
SQRT(
POWER(
SIN((53.6349994 - abs(try_convert(numeric, latitude_deg))) * pi() / 180 / 2), 2) + COS(53.6349994 * pi()/180) * COS(abs(try_convert(numeric, latitude_deg)) * pi()/180) * POWER(SIN((10.0117336 - try_convert(numeric, longitude_deg)) * pi()/180 / 2), 2) ))) AS Distance
这将防止任何转换错误。
你不应该只使用 numeric
。使用浮点表示或带小数位的东西,比如 numeric(20, 10)
.
order by
出现这种情况的原因是 SQL 优化器。您显然有一些 lat/long 值无法正确转换为 numeric
。 SQL 服务器允许自己重新安排操作,因此转换可能会在 之前 通过 where
子句进行过滤。这是整体查询优化的一部分。
我需要在我的数据库中从当前用户位置获取最近的机场 table。我找到了这个公式:https://de.scribd.com/presentation/2569355/Geo-Distance-Search-with-MySQL#page=7
所以上面link中描述的公式和我现在的情况有一些不同:示例在MySQL,我使用的是MS SQL(不是一个问题,我猜)。 lat
和 lon
被认为是具有 numeric
数据类型的数据库列,但由于某种原因,数据库 table 是用两个对应的 varchar
类型列创建的.
我的问题是:当我想使用 ORDER BY
子句时,它会抛出 Error converting data type nvarchar to numeric
,没有它,它会起作用。我对哪些垃圾作为字符串插入并迁移了它进行了一些研究,以便我只有一些空值。
我不能全部拿走,因为我只需要一个。但是,如果我在没有 ORDER BY
的情况下执行 TOP 1
,我不会得到 任何 机场而不是最近的机场。有谁知道如何修复查询?
提前致谢!
SELECT TOP 1
temp.Distance
FROM (
SELECT
(
3956 * 2 * ASIN(
SQRT(
POWER(
SIN((53.6349994 - abs(CAST(latitude_deg AS numeric))) * pi() / 180 / 2), 2) + COS(53.6349994 * pi()/180) * COS(abs(CAST(latitude_deg AS numeric)) * pi()/180) * POWER(SIN((10.0117336 - CAST(longitude_deg AS numeric)) * pi()/180 / 2), 2) ))) AS Distance
FROM Airport_Airports
WHERE
isnumeric(longitude_deg) = 1 AND isnumeric(latitude_deg) = 1 AND
longitude_deg LIKE '%[^0-9.]%' AND latitude_deg LIKE '%[^0-9.]%'
) AS temp
WHERE
temp.Distance < 50000
Order BY
temp.Distance
首先,这个逻辑说不通:
WHERE isnumeric(longitude_deg) = 1 AND
isnumeric(latitude_deg) = 1 AND
longitude_deg LIKE '%[^0-9.]%' AND
latitude_deg LIKE '%[^0-9.]%'
like
正在寻找 非数字 字符。我想你打算:
WHERE isnumeric(longitude_deg) = 1 AND
isnumeric(latitude_deg) = 1 AND
longitude_deg NOT LIKE '%[^0-9.]%' AND
latitude_deg NOT LIKE '%[^0-9.]%'
这确保值是数字。
您的问题的解决方案——至少在 SQL Server 2012+ 中——是使用 try_convert()
或 try_cast()
:
(3956 * 2 * ASIN(
SQRT(
POWER(
SIN((53.6349994 - abs(try_convert(numeric, latitude_deg))) * pi() / 180 / 2), 2) + COS(53.6349994 * pi()/180) * COS(abs(try_convert(numeric, latitude_deg)) * pi()/180) * POWER(SIN((10.0117336 - try_convert(numeric, longitude_deg)) * pi()/180 / 2), 2) ))) AS Distance
这将防止任何转换错误。
你不应该只使用 numeric
。使用浮点表示或带小数位的东西,比如 numeric(20, 10)
.
order by
出现这种情况的原因是 SQL 优化器。您显然有一些 lat/long 值无法正确转换为 numeric
。 SQL 服务器允许自己重新安排操作,因此转换可能会在 之前 通过 where
子句进行过滤。这是整体查询优化的一部分。