这是我过度简化的数据库结构;
CREATE TABLE [dbo].[Names](
[Name] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Names] PRIMARY KEY CLUSTERED
(
[Name] 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 ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Scores](
[id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
[Score] [int] NOT NULL
) ON [PRIMARY]
GO
INSERT [dbo].[Names] ([Name]) VALUES (N'a')
GO
INSERT [dbo].[Names] ([Name]) VALUES (N'b')
GO
INSERT [dbo].[Names] ([Name]) VALUES (N'c')
GO
INSERT [dbo].[Names] ([Name]) VALUES (N'd')
GO
INSERT [dbo].[Names] ([Name]) VALUES (N'e')
GO
INSERT [dbo].[Names] ([Name]) VALUES (N'f')
GO
INSERT [dbo].[Names] ([Name]) VALUES (N'g')
GO
INSERT [dbo].[Names] ([Name]) VALUES (N'h')
GO
INSERT [dbo].[Names] ([Name]) VALUES (N'i')
GO
INSERT [dbo].[Names] ([Name]) VALUES (N'j')
GO
INSERT [dbo].[Names] ([Name]) VALUES (N'k')
GO
SET IDENTITY_INSERT [dbo].[Scores] ON
GO
INSERT [dbo].[Scores] ([id], [Name], [Score]) VALUES (1, N'a', 10)
GO
INSERT [dbo].[Scores] ([id], [Name], [Score]) VALUES (2, N'b', 15)
GO
INSERT [dbo].[Scores] ([id], [Name], [Score]) VALUES (3, N'f', 12)
GO
INSERT [dbo].[Scores] ([id], [Name], [Score]) VALUES (4, N'k', 3)
GO
SET IDENTITY_INSERT [dbo].[Scores] OFF
GO
我试图获得那些得分低于12的名字,同时打印其他名称以及空数据或空数据作为分数。您可以在下图中查看所需的输出:
我使用此查询实现了目标:
;WITH cte AS
(
SELECT Names.Name, id, Score FROM Names
LEFT OUTER JOIN Scores
ON Names.Name = Scores.Name
WHERE Scores.Score < 12
)
SELECT * FROM cte
UNION ALL
SELECT Name , Null , Null
FROM Names
WHERE Names.name NOT IN
(SELECT Name FROM cte)
ORDER BY name
但不幸的是,我限制不使用CTE,因为实际查询(非简化版本)使用CTE并且不支持嵌套CTE。
你能提供另一种方法吗?
性能问题:实际查询(我在这里使用cte模仿)有超过100万行,并且已经加入了10个表,并且也可以从聚合中受益。
你很亲密你只需要将条件放在ON
子句中。
SELECT n.Name, s.id, s.Score
FROM Names n
LEFT OUTER JOIN Scores s
ON n.Name = s.Name
AND s.score < 12
这是一个Demo。
如果我理解正确你需要这个;
SELECT Names.Name, id, Score FROM Names
LEFT OUTER JOIN Scores
ON Names.Name = Scores.Name
WHERE Scores.Score < 12
Or scores.score is null
编辑John Woo指出这不正确......另一种获得正确结果集的方法(我认为)是;
SELECT Names.Name, id,
Case when Score <12 or score is null
Then null
Else score end as score
FROM Names
LEFT OUTER JOIN Scores
ON Names.Name = Scores.Name
SELECT n.Name,CASE WHEN s.Score < 12 THEN Score
ELSE NULL
FROM dbo.Names n
LEFT OUTER JOIN dbo.Scores s
ON n.Name=s.Name;
据我所知