MS SQL查询包括省略的行

问题描述 投票:0回答:3

这是我过度简化的数据库结构;

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的名字,同时打印其他名称以及空数据或空数据作为分数。您可以在下图中查看所需的输出:

desired output

我使用此查询实现了目标:

;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个表,并且也可以从聚合中受益。

sql sql-server join
3个回答
2
投票

你很亲密你只需要将条件放在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


2
投票

如果我理解正确你需要这个;

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

1
投票
   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;

据我所知

© www.soinside.com 2019 - 2024. All rights reserved.