我正在编写一些要在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
我的问题是,你能这样做吗?是否有符合此规范的命令?
谢谢,
答案 0 :(得分: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';
答案 1 :(得分:0)
MapBasic确实为您提供了对MapInfo&#39; Invert Selection&#39;这将为您提供从第一个查询中未选择的任何内容(假设您的第一个查询确实返回结果)。您可以使用它的菜单ID(在Menu.def中找到)(即311)来调用它,或者如果您在文件顶部包含menu.def,则可以通过常量M_QUERY_INVERTSELECT
来引用它。 / p>
例如。
Select * from ShipsTable where ShipType = "Barge" into Barges
Run Menu Command 311
或
Run Menu Command M_QUERY_INVERTSELECT
如果您已包含菜单定义文件。
我相信这会比按照你的例子进行第二次选择提供更好的性能,但是你不能用别名命名结果表而不做另外的选择。取决于您的用例是否值得使用,对于需要相当长时间的大型查询,它可以节省一些处理时间。