T-SQL:我能否在一个视图中查询值,然后仅在第二个视图中查询第一个视图中不存在的值?
T-SQL: Can I query one view for values and then query a second view only for values that don't exist in the first?
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
上面的代码 return 有五行。这是正确的。
名字
姓氏
位置
布兰登
雅各布斯
防御结束
凸轮
牛顿
四分卫
德兹
科比
WideReceiver
朱利安
爱德曼
WideReceiver
汤姆
布雷迪
四分卫
我的问题:
- 上面的代码片段查询并联合了两个物理 table。
- 我的真实情况涉及两个计算密集型视图。
- 从概念上讲,我想要 return 与
UNION
return 相同的结果集。
- 只是我不想在第二个 table 中查询第一个 table 中已经存在的行。
- 强调:对于小 tables,这没有明显的区别。 SQL 服务器引擎完全能够使用
UNION
子句过滤掉重复项。
- 但在我的真实情况下,我不会查询两个小的物理 table。我正在查询两个计算密集型视图。
如果你有一些不是计算密集型的键集(比如你的例子中的 id col)我认为你最好的选择是使用 temp table 来存储第一个视图的结果,然后 union ALL它与第二个一起检查它在临时 table.
中不存在
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
)
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
上面的代码 return 有五行。这是正确的。
名字 | 姓氏 | 位置 |
---|---|---|
布兰登 | 雅各布斯 | 防御结束 |
凸轮 | 牛顿 | 四分卫 |
德兹 | 科比 | WideReceiver |
朱利安 | 爱德曼 | WideReceiver |
汤姆 | 布雷迪 | 四分卫 |
我的问题:
- 上面的代码片段查询并联合了两个物理 table。
- 我的真实情况涉及两个计算密集型视图。
- 从概念上讲,我想要 return 与
UNION
return 相同的结果集。- 只是我不想在第二个 table 中查询第一个 table 中已经存在的行。
- 强调:对于小 tables,这没有明显的区别。 SQL 服务器引擎完全能够使用
UNION
子句过滤掉重复项。- 但在我的真实情况下,我不会查询两个小的物理 table。我正在查询两个计算密集型视图。
如果你有一些不是计算密集型的键集(比如你的例子中的 id col)我认为你最好的选择是使用 temp table 来存储第一个视图的结果,然后 union ALL它与第二个一起检查它在临时 table.
中不存在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
)