假设我需要找到所有已启用特定注册类型的用户的人...我想要用户的 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 的答案那么好,但我不希望经常执行此查询,所以我更喜欢可维护性而不是性能。