我对SQL并不是全新的,但这次我的速度很慢。 对于数据导出,我必须选择一些用户数据,包括两个JOIN。数据不相关,我只需要在一个出口表中同时提供这两种信息。
我创建了一个例子。 groupname 列来自一个JOIN,另一个JOIN列 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 ║
╚════╩═══════════╩══════════╩═══════════╩════════════╝
由于JOINS的性质; groupname-column现在多次重复。但我真正想要的是这样的事情:
╔════╦═══════════╦══════════╦═══════════╦════════════╗
║ 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语句会是更好的选择。不幸的是,原始查询与JOINS和where-Arguments有25行代码,所以我不想复制它。 有没有办法更容易实现我的输出方式然后做一个带有两个长查询的UNION(在这种情况下见下面的简单示例)?
SELECT u.[id]
,[firstname]
,[lastname]
,groupname
,'' AS course
FROM [dbo].[users] u
JOIN dbo.groups g ON u.id = g.userId
UNION ALL
SELECT u.[id]
,[firstname]
,[lastname]
,'' AS groupname
,course
FROM [dbo].[users] u
JOIN dbo.courses c ON u.id = c.userId
答案 0 :(得分:1)
您可以使用相关查询创建一个表值UDF,然后使用两个UDF创建一个UNION ALL
<强>临强>
- 更短的查询:
SELECT * FROM [MY_UDF](Param 1, Param 2, ...)<br/>
UNION ALL<br/>
SELECT * FROM [MY_UDF](Different Param 1, Different Param 2, ...)
<强>缺点:强>
- 您必须创建值为UDF的表。
否则:我认为QUERY_1 UNION ALL QUERY_2
可能是要走的路。
答案 1 :(得分:0)
我认为他们有很多方法可以解决你的问题。我会给你最好的想法。
第一个解决方案:只需使用WITH
不要重复您的公共部分查询,如下所示:
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
第二个解决方案:您可以将空值插入courses
和groups
并使用简单的LEFT JOIN。但我不喜欢第二种解决方案。
编辑:插入空值后,它看起来像:
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)