SQL ServeR语言 从两个联接的表数据上下文中选择单个列



假设我需要找到所有已启用特定注册类型的用户的人...我想要用户的 PersonId,以及相关注册的人。一个人可以有多个注册、多个人和多个用户。

SELECT DISTINCT person.PersonId, user.PersonId
FROM Person person
INNER JOIN Registration registration
ON person.PersonId = registration.PersonId
INNER JOIN User user
ON registration.UserId = user.UserId
WHERE person.Type = 1
AND registration.Type = 2
AND user.Enabled = 1

上面的查询有效,但我希望第一行选择人。人员 ID用户。PersonId在单个列中,而不是两个单独的列中。我知道这可以通过联合和两个单独的查询来实现,但如果可能的话,我正在尝试避免冗余。也许在这种情况下有一种更直观的方法来使用联盟?

像这样:

SELECT DISTINCT person.PersonId UNION user.PersonId
FROM Person person
...

SELECT DISTINCT person.PersonId
UNION SELECT DISTINCT user.PersonId
FROM Person person
...

我认为你不能避免工会。也许其他人可以想出一个聪明的技术,但我会这样做:

SELECT person.PersonId
FROM Person person
INNER JOIN Registration registration
ON person.PersonId = registration.PersonId
INNER JOIN User user
ON registration.UserId = user.UserId
WHERE person.Type = 1
AND registration.Type = 2
AND user.Enabled = 1
UNION
SELECT user.PersonId 
FROM Person person
INNER JOIN Registration registration
ON person.PersonId = registration.PersonId
INNER JOIN User user
ON registration.UserId = user.UserId
WHERE person.Type = 1
AND registration.Type = 2
AND user.Enabled = 1

编辑删除了CTE示例 - 最近SQL Server太多了,我忘记了mySQL不支持它们。

在 select 语句中将两个列CONCAT在一起怎么样?

SELECT CONCAT (person.PersonId,User.PersonId) AS CombinedID

但是鉴于您的上述查询,个人和用户的 id 不是相同的吗?

我现在可以看到查询的目的并不十分明确,因此这里有一些设置阶段的约束:

  • 用户就是一个人
  • 一个用户有许多注册
  • 注册可以是针对一个人的

因此,作为"现实世界"的例子;我以用户身份登录并加载了我的个人数据。其他人可以和我同时使用该帐户(想想Xbox或Netflix)。

此查询可用于查找给定注册类型的所有用户,以及他们注册的用户的人员。

无论如何,这是我使用的解决方案(感谢约翰·奥多姆的建议):

SELECT DISTINCT PersonPID = person.PersonId, UserPID = user.PersonId
INTO #TempPersonIds
FROM Person person
INNER JOIN Registration registration
ON person.PersonId = registration.PersonId
INNER JOIN User user
ON registration.UserId = user.UserId
WHERE person.Type = 1
AND registration.Type = 2
AND user.Enabled = 1
SELECT PersonPID FROM #TempPersonIds
UNION
SELECT UserPID FROM #TempPersonIds
DROP TABLE #TempPersonIds

我意识到这可能不如 Turophile 的答案那么好,但我不希望经常执行此查询,所以我更喜欢可维护性而不是性能。

最新更新