当前位置:甜馍馍地理信息网 >> 地理信息系统GIS >> 产品教程 >> 正文 >>  [阅读资讯:Mapinfo难点之SQL查询及操作大全]

Mapinfo难点之SQL查询及操作大全

[ 来源:互联网 | 时间:2007年09月25日 | 收藏本文 ] 【
随着GIS技术在各个行业的应用以及数据挖掘、空间数据采集技术、数据库技术的迅速发展,对从空间数据库发现隐含知识的需求日益增长,从而出现了用于在空间数据库中进行知识发现的技术——空间数据挖掘(Spatial Data Mining,本文简称SDM)。空间数据挖掘是从空间数据库中提取隐含的、用户感兴趣的空间和非空间模式和普遍特征的过程。

SQL查询      

SQL Select的一般步骤:

1.打开你要查询的表。你要查询的表为基础表(Base Table)

2.选择Query>SQL Select,填写SQL Select对话框满足你需要的那些分。按击OK,Mapinfo进行查询。

Mapinfo从你的基础表中抽出数据,把查询结果保存在一个被称为结果表的特殊临时表中。结果表仅有满足你的条件的行和列。结果表的默认名是Selection(尽管你可以在SQL Select对话框的Info Table Named位置上指定一个不同的结果表名)。

注意:以下第三条暗示:结果表既反映在Browser窗口,也反映在Map窗口中,换句话说,可收查询结果保存为另一个图层。保存方法见下面的第5条。

3.如果你要看查询结果,打开一个Map窗口或(和)一个Browser窗口。默认的是MapInfo自动以一个Browser窗口显示结果表(除非你清除了SQL Select对话框中的Browser Results检查盒)。

如果你的结果表被命名为Selection(默认名),Browser窗就显示一个不同的表名,例如Query1名Query2。这是因为你浏览这个Selection表的瞬间,MapInfo对该表作了一个“快拍”,并命名这个快拍为Queryn(n是数字,1或更大)。MapInfo主要按快拍是因为“Selection”是一个特殊的表名,每当你选择或不选择某些行时,Selection都在动态变化。

在SQL Select对话框中,你可以为你的结果表输入一个另外的名字(例如,你可以命名你的结果表为My-Query)。这就阻止了MapInfo把你的结果表重命名为Queryn。

4.MapInfo自动选择结果表中全部的行。这样,在你执行了SQL Select之后,你就能够接着执行选择行的全套操作。例如,你可以(通过选择Option>Region Style)对所有被选择的行提供另一种充填色,或者你能够Cut或Copy选择的全部行。

通常,你对结果表所作的任何变化都会自动作用于你的原始(基础)表。例如,如果你用SQL Select选择了基础表中的某些行,然后又从你的结果表中删除了部分行,MapInfo就会从你的表中删除相应的行。但是,如果你查询产生了小计(Subtotals),你可以改变这个结果表而不影响基础表。

5.如果你要作一个结果表的永久备份,选择File>Save As。

如果你你不执行Save As存盘,该结果表将在你退出MapInfo时被删除。

SQL Select对话框各区的填写
Select Columns区
(1)利用这个区来指定在查询表中将出现哪些列。例如查询World表,可以指定Select Columns:Country,Population,Indust_Grwth,如果你要你的结果表有与你的原表相同的列组,那就在这个区输入一个*号。

如果你要你的结果有一个与你的原表不同的列组,就要删去这个*号并输入由逗号分隔的列名(如下同)表达式列表。这个区能够包括一个*号或者一个列表达式列表,但不能同时包括这两种。要在你填Select Columns区之前填From Tables区。

如果你查询涉及的不止一个有,各个列名之前必须有它的表名,二者之间用西文句号分隔。因此,如果你要执行一个涉及两个表的查询,其中之一是Canada表,并且你要查询包括该表的Population列,那么你必须用列表达式Canada.Population。当你使用两个或多个表时,Columns下拉列表自动把表名插到各个列名之前。

(2)只选择部分列出现在结果表中是有用的,特别是你的原表有很多列而你仅需操作其中的少数列时(或许因为屏幕上只能同时显示少数列)

(3)如何输入一系列列名:

在From Tables区输入一个表名,可用键盘打入,也可用鼠标从Table下拉列表中选入。

用鼠标在Select Columns区中按击,使插入点出现在该区内。

用退格键或删除键删去*号(如果其中有*号),Select Columns区能够包含一个*号或者一串列名,但不能同时包含这两种。

从对话框右边的Columns下拉列表中选择一个列名。MapInfo把这个列名Copy到Select Columns区。

如果你的查询还包括另外一些列名,从下拉列表中选择另外的一些列名。每当你选择另外的列名时,MapInfo自动插入逗号以分隔列名。

(4)计算某些列

SQL Select能够计算出列(derived Columns)并把这些导出列存放到结果表中。导出列是MapInfo在中根据基础表中已有的一个或多个列的内容计算出的一个特殊的临时列。

例如,你的表或许含有字段Purchases92或Purchases93(分别代表各顾客在1992和1993年购物的总金额)。如果你要你的查询结果显示一个Total Purchases列,表示各顾客1992和1993年合起来的购物金额,你可以在你的Select Colomns区内包括一个导出列。在这个例子中,导出列应该有这样的形式:

Purchases 92 + Purchases 93

同样,你可能有一个包含有字段Fname(代表顾客的第一名)和Lname(顾客的后名)的顾客信息表。如果你要你的结果表包括顾客的全名,你也可以在你的Select Columns区包括一个导出列,在这个例子中,导出列会有这样的形式:

Fname + “” + Lname

为指定一个导出列,你就要在Select Columns区输入一个表达式。一个导出列表达式是若干列名,操作符(例如+和-)和函数(例如Ucase$函数,它把一个字串转换为大写的)的一个组合。

在指定导出列之前,你必须先在From Table区输入一个或多个表名。

如何指定一个导出列表达式

按Select Columns区,在该区出现插入点。
删除区内的*号
输入一个列表达式。列表达式应该包括一个或多个列名,如果表达式包括一个以上的列名,这个表达式一般包含操作符(例如+或-)来把多个列组合成为一个导出值。
有许多不同的函数和操作符能够用于列表达式中。

如果需要为列表达式指定一个别名。指定别名的方法是:在列表达式后打一个空格,然后再打入用双引号括起来的别名。
别名是可选的。如果你给了你的列表达式一个别名,那么,当你以Browser窗口显示结果表时别名就会出现在这个列的顶上。如果你没指定别名,MapInfo会用表达式的内容作为别名(例如“Fname+Lname”)。

如果需要,指定另外的列名或导出列表达式。如果你输入另外的列表达式,要输入逗号以隔开不同的表达式。
下面的例子显示一个执行加法的导出列表达式,把两个数字列的值加起来。这个例子假定Purchases92和Purchases93均为数字列:

Purchases92 + Purchases93

下一个例子显示同样的列表达式,附加上了一个可选的列别名(”Net_Purchases”):

Purchases92 + Purchases93 “Net_Purchases”

下一个例子显示一个执行除法的导出列表达式,把Poppulagion列的内容除以一百万:

Population/1000000 “Millions”

下一个例子显示一个把两个字串列组合起来的导出列表达式。这个例子假定Fname 和Lname都是字串列:

Fname+””+Lname “Full_name”

当列是字串列时,加操作符(+)执行字串联接而不是数字相加。因此,表达式Fname + “ “ + Lname产生一个由第一名紧跟空格再后跟一名组成的字串。

下一个例子显示一个导出列表达式怎样结合函数调用。Proper$函数操作一个字串值并返回一个有正常大写的字串(仅第一字母大写):

Proper$(Fname+””+Lname) “Full_name”

下一个例子显示如何用Format$函数重新格式化数字列。一般,数字列都没有包含逗号,不幸的是,这使得读大数有困难。下面的例子用Format$函数把逗号插入到Purchases93列中。这个例子假定Purchases93是一个数字列:

Format$(Purchases93,”$,#”) “Purchases_1993”,字串表达式“$,#”告诉Foramt$函数在列前显示一个美元($)并在列内插入逗号。

下一个例子显示一个导出列怎样计算基础表中各行的地理面积:

Area(Obj,”sqkm”) “Net_Area”

Obj是一特殊的列名,代表与表中各行相联系的地理对象。

Where Condition区
(1)通过行的排列顺序联接不同的表

如果两个表没有一个共同的列,你可以根据行的顺序仍然能够联接这两个表。如果你知道一个表的第一行与另一个表的第一行是相对应的,并且,一般地说,如果你知道第一个表的第n行与第二个表的第n行是对应的,那么你就可以通过引用一个名叫RowID的特殊列来联接这两个表。

RowID列含有一个整数值,代表着表中各行的行号。因此,任何表的第一行都有一个为1的RowID值,第2行有一个RowID值2,等等。

为了联接两个表,让MapInfo一个表的第n行与另一个表的第n行匹配起来,就要指定一个Where Condition表达式,形如下:

TABLE_1.RowID=TABLE_2.RowID

(2)从地理上(用地理操作符)联接不同的表

当两个表都有图形对象时,MapInfo能够根据这些对象之间的空间关系联接这两个表。所以,即使你的表没有一个共同的列,你也有可能联接不同的表。

地理操作符允许你选择某些对象,根据它们与另外的某个对象的空间关系。MapInfo有一个与地理操作符一起使用的特殊列名,“Obj”或“Object”。这个列名指的是与你的表相边系的图形对象。

地理操作符要放到所指定的对象之间,地理操作符从操作符(Operators)下拉列表中选取。

下表列出了地理操作符:

Contaions(含有)

Object A Contains Object B

(如果B的形心在A的边界内的某个位置上)

Contaions Entire(包含全部)

Object A Contains Entire Object B

(如果B的边界全部在A的边界内)

Within(在内)

Object A is Within Object B

(如果A的形心在B的边界内侧)

Entire Within(完全在内)

Objcte A is Entire Within Object B

(如果A的边界全部在B的边界内)

Intersects(相交)

Objcte A Intersects Object B

(如果它们至少有一个共同点或者它们中的一个完全在另一个内)

Contains与Within的比较是根据对象的形心,而Contains Entire与Entire Within的比较是根据整个对象。

如果A包括整个B,那么A肯定包含B,如果A完全在B内,那么A肯定在B内。

MapInfo执行简单的含有和在内比较,比执行完全含有和完全在内要快。因此,除非你绝对相信某些对象是完全在另一些对象之内,否则你应该使用Contains和Within而不用Contains Entire或Entire Within。

地理操作符提供了一种联接表的方法。当表中没有你能建立起联接的列时,你可以用地理操作符(在Where Condition区内)指定联接关系。如果你要执行一个涉及一个Cities表和一个State表的两表查询,你可以用如下的表达式之一联接两个表:

Cities.Obj Within States.Obj

States.Obj Contains Cities.Obj

在任何一种情况下,MapInfo都能找到在各个州内的全部城市,然后把代表一个城市的一个行与含有它的州的行联系起来。用同样的SQL查询,你也能够用集合功能来合计每个州的城市数,或者以州为根据总结基于城市的数据。

当你有Counties 表和一个Customers表时,Counties是多边形,Customers是点,你可以用下列地理表达式之一指一个集合联接:

Customer.obj Within County.obj

County.obj Contains Customer.obj

地理操作符与Subselects结合特别有用(见Perferming Subselects)

(3)联接两个或更多的表(根据共同字段)

一般,你是把你的资料贮存在几个不同的表中,你有你自已的数据文件,你也可能有从MapInfo购买的各种统计资料的数据库。SQL允许你建立关联以便你把这些不同表中的资料接到一起,成为一个单独的结果表。设想这样一种情况:你有一个有人口统计交资料的Counties表(各个County按年龄段、种族和职业种类的人口数统计),你还可能有关于顾客订单资料的数据库。你想检测一下这两个表,看一定种类的订单是否来自具有一定人口统计特征的Counties。或许你想根据订单与人口的统计特征的组合选择若干个Counties(县)。要做到这一点,你必须能够联接这两个表。

假设Counties表含有县名,同样订单表的一个列也含有订单来源的县名,这样,两个表都有一个共同的字段,即县名。MapInfo能够用这个共同的字段来联接这两个表。

Countyname 1980人口,1990人口 Order# Customer County

Foster 1980人口,1990人口 478001 Franic Foster

Williamette 1980人口,1990人口 478002 James Foster

Mason 1980人口,1990人口 478003 Wick mason

 

Counties表 Order表

 

在SQL Select 对话框中,你用Where Condition区告诉MapInfo如何联接这两个表。在这个区内填写如下:

Select Columns: *

Frome Table: Counties,Order

Where Condition: Counties.Countyname=Order.county

表名(在From Tables区)的顺序是重要的。如果两个表都含有Map对象,结果表将只含有排列在From Tables区中第一个表的Map对象。另外,当查询完成时,MapInfo会自动选择列在From Tables区第一个表的部分或全部行。这样,在前例中,MapInfo会选择Counties表的部分或全部行。其结果也会包括从Orders表中拷贝来的数据,但Orders表本身不会被选择。

在Where Condition区中,列的顺序必须与From Tables区中表的顺序相匹配。在上例中,From Tables区把Counties表放到了Qoders表之前,因此,Where Condition区必须把Counties.CountiName列放在Orders.County列之前。如果颠倒这两个表在From Tables区内的顺序,你也必须颠倒在Where Contition区内列名的顺序。

当你联接两个表时,结果表的行数取决两个匹配的好坏。假定你有一个10000行的Order表,要把这个Order表与有50行的States表联接。结果表可能有10000行之多。但是如果Orders表中的某些行没有与States表中的行相匹配。结果表就会少于10000行。因此,如果Orders表中有400行无state名(或许由于数据输入错误),并且如果这个关联是依赖State名,结果表就可能只有9600个行了。

当SQL Select对话框联接两个表时,你指定的如何联接这两个表的子句(Clause(s))必须放在Where Condition区内的其它子名之前。

你可以用Update Column来修改SQL Select多表联接的结果表。当你要更新一个表中带有另一个表的信息的一个列时,你可以:

用SQL Select联接这两个表。
针对Selection表使用Update Column。
更新会自动影响到相应的基础表。

(4)次选择(Subselects)

MapInfo允许SQL Select中的再次选择。再选择是放在SQL Select对话框Where Condition区内里面的一个选择语句。MapInfo首先处理Subselects,然后用这个Subselects的结果去处理主要的SQL Select。

例如,假定你要选出1990年人口大于全国各州平均值的全部州。换句话说,如果平均州人口是5百万,你要选出所有平均人口大于5百万的州。在实行中,你要在Where Condition区中使用如下的过滤标准:

Pop_1990>平均人口

然而,你并不知道那平均值是多少。但是,你知道MapInfo能够用如下集合表达式计算出那个平均值:

Avg(Pop_199)

为了计算平均州人口,要在Where Condition区输入一个再选择(Subselect)。Where Condition区那时能够比较对Pop_1990列再选择的结果。要进行那样一种查询,如下填写SQL Select对话框。

Select Columns: *

From Table: States

Where Condition: Pop_1990>(Sekect Avg(Pop_1990) From States)

再选择是在Where Condition区内,在>操作符之后。再选择必须用园括号括起来。

最有用的再选择包括一个Select子句,一个from子句和一个Where子句,象下面这样:

Select某些列from某些表where某些条件存在。

考虑如下的SQL Select,它选择各州中人口大于4000000的全部城市:

Select Columns: *

From table: cities

Where Condition: obj within any(Select obj from states where Pop_1990>4000000)

再选择返回代表1990年人口大于400000的全部州的地理对象。然后主选择语句设到被再选择选中了的州内全部城市。注意:主选择语句用了一个地理操作符(Within)来做这个事情。

虽然前一查询用两个表,States表和Cities表,但Cities是出现From Tables区的仅有的表。这是因为在再选择中使用了States。如果一个表仅仅是被用于再选择内,那么这个表的表名不需要出现在From Tables区中。

在下一个例子中,我们选择与田西纳州相交的所有州,换言之,所有相邻的州。

Select columns: *

From tables: states

Where conditions: obj Intersects(select obj from states where

state=”TN”

 

首先,MapInfo执行再选择:

Selectobj from states where state=”TN”

 

再选择找到了代表田纳西州的图形对象。然后主Where condition找到了States表中与代表田纳西州的图形相交的全部对象。你可以用类似的查询选择与某给定街道相交的全部街道。

现考虑这个例子:

Select columns: *

From Tables: County

Where Condition: County.obj contains any(select obj from dealers)

这个查询找到含有销售商的所有县。主Where condition有这样的一个形式:

一个县对象Contains一个经销商对象。

经销商对象组是由再选择:Select obj from dealers产生的。MapInfo选择代表含有经销商的各个县对象的行。

最后,对于再选择有几点注意事项:

在再选择中你可以使用在From Table区中未列出的表.但是你必须把这些表列在你的再选择的From子句中(如前面例子所示那样)。
当再选择带有关键字”any”或”all”时,再选择必须并且只能返回一个列。下面的句例是无效的,因为它试图返回两个列(State_name 和Pop_1990):
Any(Select state_name,pop_1990 from state)

当再选择不带”any”、“all”或“in”时,再选择必须准确返回一个行的值。下面的例子是无效的,因为再选择返回了一组行:
obj within(Select obj from state where Pop_1990>2000000)

当再选择不用”any”、“all”或“in”时,你不能在再选择中使用Group by Columns子句。
你不能有嵌套的再选择,即是说,每个Select语句你只能有一个再选择。
设置过滤标准

一个过滤标准是一个逻辑表达式,它通常把一个列值与某个另外的值作比较。例如,以下的过滤标准用大于操作符(>)测试订单金额列是否有大于100的值。

Where Condition:Order_Amount>100

如果一个查询包含了上面这个Where Condition子句,MapInfo就只选择那些订单金额值大于100的行。

Where Condition区可以包含两个或更多的逻辑表达式,但这些表达式必须被词“And”或“Or”隔开。如果表达式是用词And连接,MapInfo仅选择那些两个标准满足的行。如果表达式是用Or连接,MapInfo就选择满足其中任何一个标准的行。

过滤标准可用于你的基础表的任何一个列,不管你是否在Select Columns区中包括了这个列。

列可以用列名或列号来引用,列号指明是在Select Columns中已有的列的顺序。

因此,“Col”和“col6”分别指第一和第六列,号之前必须有字母“Col”。

用SQL Select对话框的Where Condition区的基本目的可能是两个:行过滤和关联。Where condition区服务于多个目的。在某些场合下,你可能要用一个Where condition表达式来过滤你的表,以便你只看到满足一定标准的那些列。在一些场合下,你要利用Where condition区来指定一种关联,以便你的查询能够包括来自两个或更多个表中的列。

注意:你不可以在Where condition区中使用集合函数(apgregate function)。

Order by Columns(按列排序)区

选择升序和降序

默认,MapInfo是用升序排序一个表。如果你要用一个字符型字段进行排序,升序意味着A出现在B之上,如此类推。如果你对一个数字型字段进行排序,小的数值出现在大的数值之上。

为了以降序排序,以便大的数出现在小的数之上,要在Order By Columns区中的列名之后放一个词desc。例如,你查询World表,用如下的方式:

下一页
本文共 2 页,第  [1]  [2]  页

【推荐本文】 【打印本页】 【返回顶部
最新文章
推荐文章