本主题将介绍 ArcGIS 中常见选择查询的各个元素。 ArcGIS 中的查询表达式使用 SQL 语法。
常见查询:搜索字符串
查询中的字符串必须始终用单引号括起,例如:
STATE_NAME = 'California'
表达式中的字符串区分大小写。 要进行区分大小写的搜索,可使用 SQL 函数将所有值转换为相同的大小写形式。 对于基于文件的数据源(例如地理数据库或 shapefile),可使用 UPPER 或 LOWER 函数设置选择的大小写形式。 例如,以下表达式将选择名称存储为“Rhode Island”或“RHODE ISLAND”的州:
UPPER(STATE_NAME) = 'RHODE ISLAND'
如果字符串包含单引号,您首先需要使用另一单引号作为转义字符,例如:
NAME = 'Alfie''s Trough'
可以使用 LIKE 运算符(而非 = 运算符)来构建部分字符串搜索。 例如,以下表达式将从美国州名称中选择 Mississippi 和 Missouri:
STATE_NAME LIKE 'Miss%'
百分号 (%) 表示这个位置可以是任意字符,即 1 个字符、100 个字符或者无字符均可。 此外,如果您希望在查询时通配符仅代表一个字符,可使用下划线 (_)。 例如,以下表达式会找到 Catherine Smith 和 Katherine Smith:
OWNER_NAME LIKE '_atherine smith'
还可使用大于 (>)、小于 (<)、大于等于 (>=)、小于等于 (<=)、不等于 (<>) 以及 BETWEEN 运算符来基于排序顺序选择字符串值。 例如,以下表达式将选择 coverage 中名称首字母为 M 到 Z 的所有城市:
CITY_NAME >= 'M'
字符串函数可用来格式化字符串。 例如,LEFT 函数将返回字符串左侧特定数量的字符。 在以下示例中,查询将返回以字母 A 开头的所有州:
LEFT(STATE_NAME,1) = 'A'
有关支持的函数列表,请参阅数据库管理系统文档。
常见表达式:搜索空值
可使用 NULL 关键字来选择指定字段为空值的要素和记录。 NULL 关键字的前面始终使用 IS 或 IS NOT。 例如,要查找尚未输入 1996 年人口的城市,可使用以下表达式:
POPULATION IS NULL
或者,要查找已输入 1996 年人口的城市,可使用以下表达式:
POPULATION96 IS NOT NULL
常见表达式:搜索数值
无论您的区域设置如何,小数点 (.) 将始终用作小数分隔符。 在表达式中不能使用逗号作为小数分隔符或千位分隔符。
可以使用等于 (=)、不等于 (<>)、大于 (>)、小于 (<)、大于等于 (>=)、小于等于 (<=) 和 BETWEEN 运算符查询数值,例如:
POPULATION >= 5000
数值函数可用来格式化数值。 例如,ROUND 函数可将文件地理数据库中的数值四舍五入到指定的小数位数:
ROUND(SQKM,0) = 500
有关支持的数值函数列表,请参阅数据库管理系统文档。
日期和时间
通用规则和常见表达式
地理数据库数据源将日期保存在日期时间字段中。 但是,ArcInfo coverage 和 shapefile 不是这样。 因此,下面所列的大部分查询语法都包含对时间的引用。 在某些情况下,当已知字段只包含日期时,查询中的时间部分可以安全地省略掉;而在其他情况下则必须进行声明,否则查询将返回语法错误。
搜索日期字段需要格外注意数据源所需的语法。 如果在查询构建器的“子句”模式下构建日期查询,将自动为用户生成正确的语法。 以下是从文件地理数据库数据源返回 2011 年 1 月 1 日及以后所有记录的查询示例:
INCIDENT_DATE >= date '2011-01-01 00:00:00'
注:
基础数据库中日期的存储会参考 1899 年 12 月 30 日 00:00:00。 这适用于此处所列出的所有数据源。
本部分内容的目的只是帮助您查询日期值,而非时间值。 当存储了包含非空时间的日期(例如 1999 年 1 月 12 日 04:00:00)后,只查询该日期将不会返回这条记录,因为当向一个日期时间字段只传递日期时,系统会自动用零填充时间,所以将只检索该日期下时间为 12:00:00 a.m 的记录。
属性表内会以用户友好的格式来显示日期和时间(取决于用户的区域设置)而不是采用基础数据库的格式。 这在大多数情况下都很适用,但也存在以下缺点:
- SQL 查询中显示的字符串可能会与表中显示的值稍有不同,尤其是当包含时间时。 例如,输入的时间 00:00:15 将在属性表中(当您的区域设置为美国时)显示为 12:00:15 a.m.,对应于查询语法将是 Datefield = '1899-12-30 00:00:15'。
- 属性表在您保存编辑之前无法知道是何种基础数据源。 它首先会尝试将输入的值格式化为符合自己的格式,然后在保存编辑内容时,会再尝试对生成的值进行调整以便存入数据库。 因此,您可以在 shapefile 中输入一个时间值,但您会发现当您保存编辑内容时该值会被丢弃。 随后该字段将包含值“1899-12-30”并显示 12:00:00 a.m. 或其他等效的值(取决于您的区域设置)。
企业级地理数据库的日期时间语法
Informix
Datefield = 'yyyy-mm-dd hh:mm:ss'
查询的 hh:mm:ss 部分不能省略,即使等于 00:00:00 也是如此。
Oracle
Datefield = date 'yyyy-mm-dd'
请切记,这将不会返回时间不为空的记录。
在 Oracle 中查询日期的替代格式如下:
Datefield = TO_DATE('yyyy-mm-dd hh:mm:ss','YYYY-MM-DD HH24:MI:SS')
第二个参数 'YYYY-MM-DD HH24:MI:SS' 用于描述查询要用的格式。 实际的查询可能类似于:
Datefield = TO_DATE('2003-01-08 14:35:00','YYYY-MM-DD HH24:MI:SS')
您可以使用精简形式:
TO_DATE('2003-11-18','YYYY-MM-DD')
同样,这将不会返回时间不为空的记录。
SQL Server
Datefield = 'yyyy-mm-dd hh:mm:ss'
当记录中未设置时间时,查询的 hh:mm:ss 部分可以省略。
替代格式如下:
Datefield = 'mm/dd/yyyy'
IBM DB2
Datefield = TO_DATE('yyyy-mm-dd hh:mm:ss','YYYY-MM-DD HH24:MI:SS')
查询的 hh:mm:ss 部分不能省略,即使时间等于 00:00:00 也是如此。
PostgreSQL
Datefield = TIMESTAMP 'YYYY-MM-DD HH24:MI:SS' Datefield = TIMESTAMP 'YYYY-MM-DD'
使用“等于”查询时必须指定完整的时间戳,否则将不会返回任何记录。 如果查询的表中包含这些确切的时间戳(2007-05-29 00:00:00 或 2007-05-29 12:14:25)时,您可以用下列语句成功进行查询:
select * from table where date = '2007-05-29 00:00:00';
或
select * from table where date = '2007-05-29 12:14:25';
如果您使用其他运算符(如大于、小于、大于等于或小于等于),则无需指定时间,不过如果您希望更精确些也可以指定。 以下两个语句都可以使用:
select * from table where date < '2007-05-29';
select * from table where date < '2007-05-29 12:14:25';
文件地理数据库、shapefile、coverage 和其他基于文件的数据源
文件地理数据库、shapefile 和 coverage 中的日期前面要加上 date。
Datefield = date 'yyyy-mm-dd'
文件地理数据库支持在日期字段中使用时间,因此可将此加入到表达式中:
Datefield = date 'yyyy-mm-dd hh:mm:ss'
Shapefile 和 coverage 不支持在日期字段中使用时间。
注:
文件地理数据库所用的所有 SQL 均基于 SQL-92 标准。
已知局限性
对连接的左侧部分(第一张表)的日期查询只适用于基于文件的数据源,如文件地理数据库、shapefile 和 DBF 表。 不过,对于非基于文件的数据(如企业数据)也有解决方法,如下文所述。
当使用为基于文件的数据源所开发的受限的 SQL 版本时,对连接的左侧部分的日期查询将获得成功。 如果您没有使用此类数据源,可以强制表达式使用这种格式。 您可以通过确保查询表达式涉及一个以上连接表的字段来实现此操作。 例如,如果要素类和表(FC1 和 Table1)进行连接且均来自于企业级地理数据库,则下列表达式将失败或不返回任何数据:
FC1.date = date #01/12/2001# FC1.date = date '01/12/2001'
要想查询成功,您可以创建如下查询:
FC1.date = date '01/12/2001' and Table1.OBJECTID > 0
由于此查询涉及到两个表的字段,因此将使用受限的 SQL 版本。 在此表达式中,连接创建期间匹配记录的 Table1.OBJECTID 始终为 > 0,因此对于包含连接匹配项的所有行来说此表达式均为 true。
要确保选择 FC1.date = date '01/12/2001' 的每条记录,可使用下列查询:
FC1.date = date '01/12/2001' and (Table1.OBJECTID IS NOT NULL OR Table1.OBJECTID IS NULL)
此查询将选择 FC1.date = date '01/12/2001' 的所有记录,而无论每条记录是否是连接匹配项。
组合表达式
通过使用 AND 和 OR 运算符将表达式组合在一起,可构建复合表达式。 例如,以下表达式将选择面积超过 1,500 平方英尺的所有房屋和一个可容纳三台或更多汽车的车库。
AREA > 1500 AND GARAGE > 3
如果使用 OR 运算符,OR 运算符两侧的两个表达式中必须至少有一个为真时才会选择记录,例如:
RAINFALL < 20 OR SLOPE > 35
在表达式开头使用 NOT 运算符可查找与指定表达式不匹配的要素或记录,例如:
NOT STATE_NAME = 'Colorado'
NOT 表达式可与 AND 和 OR 组合。 例如,以下表达式将选择除 Maine 以外的所有新英格兰州。
SUB_REGION = 'New England' AND NOT STATE_NAME = 'Maine'
计算
可使用算术运算符 +、-、* 和 / 在查询中加入计算: 可在字段和数字之间进行计算,例如:
AREA >= PERIMETER * 100
也可在字段之间进行计算。 例如,要查找人口密度小于等于每平方英里 25 人的所有国家,可使用以下表达式:
POP1990 / AREA <= 25
运算符优先级
表达式求值顺序遵照标准的运算符优先级规则。 例如,求值时,首先计算括号内部的表达式部分,然后再计算其他部分。
HOUSEHOLDS > MALES * (POP90_SQMI + AREA)
可以通过输入括号的方式在 SQL 编辑模式下添加括号,也可以在“子句”模式下使用“组”或“取消分组”命令添加或移除括号。
子查询
子查询是嵌套在另一个查询中的查询,仅受地理数据库数据源支持。 子查询可用于应用谓词或聚合函数,或将数据与存储在另一张表中的值进行比较。 可使用 IN 或 ANY 关键字来执行此操作。 例如,以下查询只会选择未在 indep_countries 表中列出的国家:
COUNTRY_NAME NOT IN (SELECT COUNTRY_NAME FROM indep_countries)
注:
coverage、shapefile 和其他基于非地理数据库文件的数据源不支持子查询。 在版本化企业级要素类和表上执行的子查询不会返回增量表中存储的要素。 文件地理数据库对本部分所述的子查询提供了有限的支持,而企业级地理数据库则提供完全支持。 有关企业级地理数据库中全套子查询功能方面的详细信息,请参阅您的数据库管理系统文档。
此查询将返回国家中 GDP2006 大于 GDP2005 的所有要素:
"GDP2006" > (SELECT MAX("GDP2005") FROM countries)
文件地理数据库仅提供对以下子查询的支持:
- 包含比较运算符的标量子查询。 标量子查询返回单个值,例如:
对于文件地理数据库,集合函数 AVG、COUNT、MIN、MAX 和 SUM 只能用在标量子查询内。"GDP2006" > (SELECT MAX("GDP2005") FROM countries)
- EXISTS 谓词,例如:
EXISTS (SELECT * FROM indep_countries WHERE "COUNTRY_NAME" = 'Mexico')
运算符
以下是文件地理数据库、shapefile、coverage 和其他基于文件的数据源所支持的查询运算符的完整列表。 企业级地理数据库也支持这些运算符,但这些数据源可能使用不同的语法。 除了以下这些运算符外,企业级地理数据库还支持一些其他功能。 有关详细信息,请参阅数据库管理系统文档。
算术运算符
算术运算符用于对数值进行加、减、乘、除的运算。
运算符 | 描述 |
---|---|
* | 乘法算术运算符 |
/ | 除法算术运算符 |
+ | 加法算术运算符 |
- | 减法算术运算符 |
比较运算符
使用比较运算符可以将两个表达式进行比较。
运算符 | 描述 |
---|---|
< | 小于。 适用于字符串(基于字母顺序进行比较)、数值和日期。 |
<= | 小于或等于。 适用于字符串(基于字母顺序进行比较)、数值和日期。 |
<> | 不等于。 适用于字符串(基于字母顺序进行比较)、数值和日期。 |
> | 大于。 适用于字符串(基于字母顺序进行比较)、数值和日期。 |
>= | 大于或等于。 适用于字符串(基于字母顺序进行比较)、数值和日期。 |
[NOT] BETWEEN x AND y | 选择值大于等于 x 且小于等于 y 的记录。 如果前面有 NOT,则将选择值在指定范围之外的记录。 例如,以下表达式将选择值大于等于 1 且小于等于 10 的所有记录:
这与以下表达式等效:
但是,在查询具有索引的字段时使用包含 BETWEEN 的表达式效率会更高。 |
[NOT] EXISTS | 如果子查询返回至少一条记录则返回 TRUE;否则返回 FALSE。 例如,如果 OBJECTID 字段包含一个值 50,则以下查询将返回 TRUE:
只有文件地理数据库和企业级地理数据库支持 EXISTS。 |
[NOT] IN | 如果记录的某个字段包含多个字符串或值的其中一个,那么选择这条记录。 当表达式前面包含 NOT 时,如果记录的某个字段不包含多个字符串或值的任何一个,那么将选择这条记录。 例如,以下表达式将搜索四个不同的州名称: |
IS [NOT] NULL | 选择指定字段为空值的记录。 如果 NULL 前面有 NOT,则将选择指定字段中包含任意值的记录。 |
x [NOT] LIKE y [ESCAPE '转义字符'] | 将 LIKE 运算符(不是 = 运算符)与通配符结合使用可以构建对部分字符串的搜索。 百分号 (%) 表示这个位置可以是任意字符,即 1 个字符、100 个字符或者无字符均可。 此外,如果您希望在查询时通配符仅代表一个字符,可使用下划线 (_)。 如果需要访问非字符数据,请使用 CAST 函数。 例如,以下查询将返回整数字段 SCORE_INT 中以 8 开头的数值:
要在搜索字符串中包含百分号或下划线,请使用 ESCAPE 关键字来将另一种字符指定为转义字符,该字符表示紧接其后的是真正的百分号或下划线。 例如,以下表达式将返回任何包含 10% 的任何字符串,例如 10% DISCOUNT 或 A10%: |
逻辑运算符
运算符 | 描述 |
---|---|
AND | 结合两个条件,如果两个条件都为 true 则选择记录。 例如,以下表达式将选择面积大于 1,500 平方英尺且有一个能容纳 2 台以上汽车的车库的所有房屋:
|
OR | 结合两个条件,如果两个条件中至少有一个为 true 则选择记录。 例如,以下表达式将选择面积大于 1,500 平方英尺或有一个能容纳 2 台以上汽车的车库的所有房屋:
|
NOT | 选择与表达式不匹配的记录。 例如,以下表达式将选择除 California 之外的所有州:
|
字符串运算符
运算符 | 描述 |
---|---|
|| | 返回连接两个或多个字符串表达式后得到的字符串。
|
函数
以下是文件地理数据库、shapefile、coverage 和其他基于文件的数据源所支持的函数的完整列表。 企业级地理数据库也支持这些函数,但这些数据源可能需要不同的语法或函数名。 除了以下这些函数外,企业级地理数据库还支持一些其他功能。 有关详细信息,请参阅数据库管理系统文档。
日期函数
功能 | 描述 |
---|---|
CURRENT_DATE | 返回当前日期。 |
EXTRACT(extract_field FROM extract_source) | 返回 extract_source 的 extract_field 部分。 extract_source 参数是一个日期时间表达式。 extract_field 参数可以是下列任一关键字:年、月、日、小时、分钟或秒。 |
CURRENT TIME | 返回当前时间。 |
字符串函数
以 string_exp 表示的参数可以是列名、字符串文本或者另一个标量函数的结果,其基础数据类型可表示为字符型。
以 character_exp 表示的参数是长度可变的字符型字符串。
以 start 或 length 表示的参数可以是数值文本或者另一个标量函数的结果,其基础数据类型可表示为数值型。
这些字符串函数以 1 为基础;即字符串的第一个字符为字符 1。
功能 | 描述 |
---|---|
CHAR_LENGTH(string_exp) | 返回字符串表达式的字符长度。 |
LOWER(string_exp) | 返回一个与 string_exp 相等的字符串,其中所有大写字符均会转换为小写字符。 |
POSITION(character_exp IN character_exp) | 返回第一个字符表达式在第二个字符表达式中的位置。 结果是一个确切的数值,采用预先定义的精度且小数位数为零。 |
SUBSTRING(string_exp FROM start FOR length) | 返回一个从 string_exp 衍生而来的字符串,其起始字符位置由 start 指定,字符数由 length 指定。 |
TRIM(BOTH | LEADING | TRAILING trim_character FROM string_exp) | 返回字符串的开头、末尾或两端移除 trim_character 后所得的 string_exp。 |
UPPER(string_exp) | 返回一个与 string_exp 相等的字符串,其中所有小写字符均会转换为大写字符。 |
数值函数
所有数值函数均返回数值型值。
以 numeric_exp、float_exp 或 integer_exp 表示的参数可以是列名、另一个标量函数的结果或数值文本,其基础数据类型可表示为数值型。
功能 | 描述 |
---|---|
ABS(numeric_exp) | 返回 numeric_exp 的绝对值。 |
ACOS(float_exp) | 返回作为角度的 float_exp 的反余弦值,用弧度表示。 |
ASIN(float_exp) | 返回作为角度的 float_exp 的反正弦值,用弧度表示。 |
ATAN(float_exp) | 返回作为角度的 float_exp 的反正切值,用弧度表示。 |
CEILING(numeric_exp) | 返回大于或等于 numeric_exp 的最小整数。 |
COS(float_exp) | 返回 float_exp 的余弦值,其中 float_exp 是以弧度表示的角度。 |
FLOOR(numeric_exp) | 返回小于或等于 numeric_exp 的最大整数。 |
LOG(float_exp) | 返回 float_exp 的自然对数。 |
LOG10(float_exp) | 返回 float_exp 的以 10 为底的对数。 |
MOD(integer_exp1, integer_exp2) | 返回 integer_exp1 除以 integer_exp2 所得的余数。 |
POWER(numeric_exp, integer_exp) | 返回 numeric_exp 的 integer_exp 次幂的值。 |
ROUND(numeric_exp, integer_exp) | 返回四舍五入至小数点右侧第 integer_exp 位的 numeric_exp。 如果 integer_exp 为负数,则 numeric_exp 将被四舍五入至小数点左侧第 |integer_exp| 位。 |
SIGN(numeric_exp) | 返回 numeric_exp 正负号的标志。 如果 numeric_exp 小于零,则返回 -1。 如果 numeric_exp 等于零,则返回 0。 如果 numeric_exp 大于零,则返回 1。 |
SIN(float_exp) | 返回 float_exp 的正弦值,其中 float_exp 是以弧度表示的角度。 |
TAN(float_exp) | 返回 float_exp 的正切值,其中 float_exp 是以弧度表示的角度。 |
TRUNCATE(numeric_exp, integer_exp) | 返回截断至小数点右侧第 integer_exp 位的 numeric_exp。 如果 integer_exp 为负数,则 numeric_exp 将被截断至小数点左侧第 |integer_exp| 位。 |
CAST 函数
CAST 函数可将值转换为指定的数据类型。 语法如下:
CAST(exp AS data_type)
exp 参数可以是列名、另一个标量函数的结果或是一个文本。 Data_type 可以是下列任意关键字,可以用大写或小写形式指定:CHAR、VARCHAR、INTEGER、SMALLINT、REAL、DOUBLE、DATE、TIME、DATETIME、NUMERIC 或 DECIMAL。