SQL - 将查询数据流拆分为2个单独的表[理论优化]

时间:2016-05-06 21:10:11

标签: sql sql-server sql-server-2008 mapinfo map-basic

我正在编写一些要在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

我的问题是,你能这样做吗?是否有符合此规范的命令?

谢谢,

2 个答案:

答案 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

enter image description here

或者您可以使用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';

enter image description here

答案 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如果您已包含菜单定义文件。

我相信这会比按照你的例子进行第二次选择提供更好的性能,但是你不能用别名命名结果表而不做另外的选择。取决于您的用例是否值得使用,对于需要相当长时间的大型查询,它可以节省一些处理时间。