我正在编写一些用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我的问题是,你能做到吗?有符合这个规范的命令吗?
谢谢,
发布于 2016-05-09 07:52:57
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-06 21:39:45
在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';

https://stackoverflow.com/questions/37081480
复制相似问题