2

我正在编写一些要在 MapBasic(MapInfo 的编程语言)中运行的 SQL 代码。描述问题的最佳方式是举个例子:

我想将 ShipType="Barge" 的所有记录选择到名为 Barges 的查询中,并且我希望将所有剩余记录放入查询 OtherShips 中。

我可以简单地使用以下 SQL 命令:

select * from ShipsTable where  ShipType = "Barge" into Barges
select * from ShipsTable where  ShipType <> "Barge" into OtherShips

这很好,但我不禁觉得这是低效的。SQL 不会在数据库中搜索两次吗?在第一个查询的处理过程中,它不会找到适合第二个查询的数据行吗?

相反,如果有这样的命令会更快:

select * from ShipsTable where ShipType = "Barge" into Barges ELSE into OtherShips

我的问题是,你能做到吗?是否有适合此规范的命令?

谢谢,

4

2 回答 2

1

您可以在具有条件拆分和两个不同目的地的 SSIS 中轻松完成此操作。

但不是真的在 TSQL 中。

然而,为了“有趣”,下面将介绍一些可能性。

您可以创建一个分区视图,但是您需要满足的要求非常艰巨,执行计划只是将其全部加载到一个假脱机中,然后使用两个不同的过滤器读取假脱机两次。

CREATE TABLE Barges
(
Id INT,
ShipType VARCHAR(50) NOT NULL CHECK (ShipType = 'Barge'),
PRIMARY KEY (Id, ShipType)
)

CREATE TABLE OtherShips
(
Id INT,
ShipType VARCHAR(50) NOT NULL CHECK (ShipType <> 'Barge'),
PRIMARY KEY (Id, ShipType)
)

CREATE TABLE ShipsTable
(
ShipType VARCHAR(50) NOT NULL
)

go

CREATE VIEW ShipsView
AS
SELECT *
FROM Barges
UNION ALL
SELECT *
FROM OtherShips

GO

INSERT INTO ShipsView(Id, ShipType)
SELECT ROW_NUMBER() OVER(ORDER BY @@SPID), ShipType
FROM ShipsTable

在此处输入图像描述

或者您可以使用OUTPUT子句和可组合 DML,但这需要将两组行都插入到第一个表中,然后清除不需要的行(第二个表只会获得正确的行,不需要任何清理)。

CREATE TABLE Barges2
(
ShipType VARCHAR(50) NOT NULL
)

CREATE TABLE OtherShips2
(
ShipType VARCHAR(50) NOT NULL
)

CREATE TABLE ShipsTable2
(
ShipType VARCHAR(50) NOT NULL
)

INSERT INTO Barges2
SELECT *
FROM 
(
INSERT INTO OtherShips2
OUTPUT INSERTED.*
SELECT *
FROM ShipsTable2
) D
WHERE D.ShipType = 'Barge';

DELETE FROM OtherShips2 WHERE ShipType = 'Barge';

在此处输入图像描述

于 2016-05-06T21:39:45.103 回答
0

MapBasic 确实为您提供了访问 MapInfo 的“反转选择”的权限,这将为您提供第一个查询中未选择的任何内容(假设您的第一个查询确实返回结果)。您可以使用它的菜单 ID(在 Menu.def 中找到)311 来调用它,或者如果您在文件顶部包含 menu.def,您可以通过常量引用它M_QUERY_INVERTSELECT

例如。

Select * from ShipsTable where  ShipType = "Barge" into Barges
Run Menu Command 311

或者 Run Menu Command M_QUERY_INVERTSELECT如果您已包含菜单定义文件。

我相信这会给您带来比根据您的示例进行第二次选择更好的性能,但是如果不进行其他选择,您将无法使用别名命名结果表。取决于您的用例是否值得使用,对于需要很长时间的大型查询,它可以很好地节省一些处理时间。

于 2016-05-09T07:52:57.520 回答