sql-server - T-SQL:我可以查询一个视图的值,然后只查询第二个视图中不存在的值吗?
问题描述
DROP TABLE IF EXISTS ..Players
DROP TABLE IF EXISTS ..FreeAgents
CREATE TABLE [dbo].[FreeAgents](
[Id] [int] IDENTITY(1,1) NOT NULL,
[FirstName] [nvarchar](50) NOT NULL,
[LastName] [nvarchar](50) NOT NULL,
[Position] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_FreeAgents] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Players](
[Id] [int] IDENTITY(1,1) NOT NULL,
[FirstName] [nvarchar](50) NOT NULL,
[LastName] [nvarchar](50) NOT NULL,
[Position] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Players] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[FreeAgents] ON
GO
INSERT [dbo].[FreeAgents] ([Id], [FirstName], [LastName], [Position]) VALUES (2, N'Julian', N'Edelman', N'WideReceiver')
GO
INSERT [dbo].[FreeAgents] ([Id], [FirstName], [LastName], [Position]) VALUES (3, N'Dez', N'Bryant', N'WideReceiver')
GO
INSERT [dbo].[FreeAgents] ([Id], [FirstName], [LastName], [Position]) VALUES (4, N'Brandon', N'Jacobs', N'DefensiveEnd')
GO
SET IDENTITY_INSERT [dbo].[FreeAgents] OFF
GO
SET IDENTITY_INSERT [dbo].[Players] ON
GO
INSERT [dbo].[Players] ([Id], [FirstName], [LastName], [Position]) VALUES (1, N'Tom', N'Brady', N'Quarterback')
GO
INSERT [dbo].[Players] ([Id], [FirstName], [LastName], [Position]) VALUES (2, N'Cam', N'Newton', N'Quarterback')
GO
INSERT [dbo].[Players] ([Id], [FirstName], [LastName], [Position]) VALUES (3, N'Julian', N'Edelman', N'WideReceiver')
GO
SET IDENTITY_INSERT [dbo].[Players] OFF
GO
SELECT FirstName, LastName, Position FROM ..Players
UNION
SELECT FirstName, LastName, Position FROM ..FreeAgents
上面的代码返回五行。这是对的。
名 | 姓 | 位置 |
---|---|---|
布兰登 | 雅各布斯 | 防守端 |
凸轮 | 牛顿 | 四分卫 |
德兹 | 科比 | 宽接收器 |
朱利安 | 爱德曼 | 宽接收器 |
汤姆 | 布雷迪 | 四分卫 |
我的问题:
- 上面的代码片段查询并联合了两个物理表。
- 我的实际情况涉及两个计算密集型视图。
- 从概念上讲,我想返回与 a
UNION
返回相同的结果集。- 除了我不想在第二个表中查询第一个表中已经存在的行。
- 强调:对于小桌子,这没有明显的区别。SQL Server 引擎完全能够使用该
UNION
子句过滤掉重复项。- 但在我的实际情况中,我不是在查询两个小的物理表。我正在查询两个计算密集型视图。
解决方案
如果您有一些不是计算密集型的键集(例如您的示例中的 id col),我认为您最好的选择是使用临时表来存储第一个视图的结果,然后将其与第二个视图合并,其中检查它没有存在于临时表中。
SELECT * FROM view1
INTO #v1;
SELECT * FROM #v1
UNITON ALL
SELECT * FROM view2
WHERE NOT EXISTS(SELECT 1 FROM #v1 WHERE #v1.id = view2.id)
第二个视图应该只对丢失的记录执行计算。
使用WITH
语句可能会更好,但我不确定 - 这需要在真实数据上进行测试。
WITH v1 AS (SELECT * FROM view1)
SELECT * FROM v1
UNION ALL
SELECT * FROM view2
WHERE NOT EXISTS (
SELECT 1 FROM v1
WHERE v1.id = view2.id -- Set duplicate condition here
)
推荐阅读
- ansible - 我可以在 ansible 中设置一个任务以仅在文件夹存在的情况下运行吗?
- cygwin - 关于 Cygwin Windows 编译问题的 Wine
- python - PyNGL/PyNio 的资源文件问题
- c++ - 密码生成器:如何让每个密码换行?
- c - 如何阅读最后一个字符为“n”的句子
- redux-persist - Redux-persist 在 React / connected-react-router 中的实现
- javascript - 如何禁用子域的服务工作者?
- oracle - 如何将 JDeveloper 创建的 BPEL 流程转换为 WSO2 BPEL 流程
- angular - 为 Angular 库配置大小预算
- dart - Why conditionally cast to an interface type fails in dart?