Sql server SQL:多个选择而不是联接
我对SQL并不完全陌生,但这次我对SQL的理解很慢。 对于数据导出,我必须选择一些包含两个联接的用户数据。数据不相关,我只需要在一个导出表中同时包含这两个信息 我创造了一个例子。列groupname来自一个联接,列course来自另一个联接:Sql server SQL:多个选择而不是联接,sql-server,join,union,Sql Server,Join,Union,我对SQL并不完全陌生,但这次我对SQL的理解很慢。 对于数据导出,我必须选择一些包含两个联接的用户数据。数据不相关,我只需要在一个导出表中同时包含这两个信息 我创造了一个例子。列groupname来自一个联接,列course来自另一个联接: ╔════╦═══════════╦══════════╦═══════════╦════════════╗ ║ id ║ firstname ║ lastname ║ groupname ║ course ║ ╠════╬═══════════╬
╔════╦═══════════╦══════════╦═══════════╦════════════╗
║ id ║ firstname ║ lastname ║ groupname ║ course ║
╠════╬═══════════╬══════════╬═══════════╬════════════╣
║ 1 ║ John ║ Doe ║ Manager ║ Management ║
║ 1 ║ John ║ Doe ║ CEO ║ Management ║
║ 1 ║ John ║ Doe ║ Manager ║ Logistics ║
║ 1 ║ John ║ Doe ║ CEO ║ Logistics ║
║ 1 ║ John ║ Doe ║ Manager ║ Leadership ║
║ 1 ║ John ║ Doe ║ CEO ║ Leadership ║
╚════╩═══════════╩══════════╩═══════════╩════════════╝
由于连接的性质;groupname列现在重复了几次。但我真正想要的是这样的:
╔════╦═══════════╦══════════╦═══════════╦════════════╗
║ id ║ firstname ║ lastname ║ groupname ║ course ║
╠════╬═══════════╬══════════╬═══════════╬════════════╣
║ 1 ║ John ║ Doe ║ Manager ║ ║
║ 1 ║ John ║ Doe ║ CEO ║ ║
║ 1 ║ John ║ Doe ║ ║ Management ║
║ 1 ║ John ║ Doe ║ ║ Logistics ║
║ 1 ║ John ║ Doe ║ ║ Leadership ║
╚════╩═══════════╩══════════╩═══════════╩════════════╝
我想,连续做两个SELECT语句是更好的选择。不幸的是,带有连接和where参数的原始查询大约有25行代码,因此我不想重复它。
有没有一种方法比使用两个长查询进行联合更容易实现我的输出方式(本例中的简单示例见下文)
您可以使用所讨论的查询创建一个表值UDF,然后使用两个UDF创建一个UNION Pro:
-更短的查询:
SELECT * FROM [MY_UDF](Param 1, Param 2, ...)<br/>
UNION ALL<br/>
SELECT * FROM [MY_UDF](Different Param 1, Different Param 2, ...)
从[MY_UDF](参数1,参数2,…)中选择*
联合所有人
从[我的自定义项]中选择*(不同的参数1,不同的参数2,…)
反对意见:-您必须创建表值UDF。
否则:我认为
QUERY\u 1 UNION ALL QUERY\u 2
可能是解决问题的方法。我认为他们有很多方法可以解决您的问题。我会给你我能想到的最好的方法
第一种解决方案:只需将与
一起使用,即可不重复常见零件查询,如下所示:
WITH CommonPart (id, firstname, lastname)
AS
(
Select id, firstname, lastname
From [dbo].[users]
-- Eventually a filter ...
)
SELECT cp.*
, g.groupname
, '' AS course
FROM CommonPart cp
JOIN dbo.groups g ON cp.id = g.userId
UNION ALL
SELECT cp.*
,'' AS groupname
,c.course
FROM CommonPart cp
JOIN dbo.courses c ON cp.id = c.userId
第二种解决方案:您可以在课程
和组
中插入空值,并使用简单的左连接。但我不喜欢第二种解决方案
编辑:插入空值后,它将如下所示:
Select u.id,
u.firstname,
u.lastname,
g.groupname,
c.course
From [dbo].[users] u
Left Join [dbo].[groups] g ON g.userId = u.id
Left Join [dbo].[courses] c ON c.userId = u.id
Where (g.groupname IS NULL and c.course IS NOT NULL)
OR (g.groupname IS NOT NULL and c.course IS NULL)
您能提供每个表的一些示例数据吗?这不是MySQL语法,这是ms sql。删除了MySQL标签。
union all
与此相当好。第一个解决方案就像一个charme。我没有想到要用。通常,我只将其用于递归。唯一的缺点是,我必须在另一个查询中对列的顺序进行重新排序(我在表值函数中使用此代码,以便为过滤器使用参数)
Select u.id,
u.firstname,
u.lastname,
g.groupname,
c.course
From [dbo].[users] u
Left Join [dbo].[groups] g ON g.userId = u.id
Left Join [dbo].[courses] c ON c.userId = u.id
Where (g.groupname IS NULL and c.course IS NOT NULL)
OR (g.groupname IS NOT NULL and c.course IS NULL)