Sql server 如何将左连接与一组其他连接一起使用
我正在尝试基于EquipWorkOrderID连接两个表。表(设备工单和设备工单) 在下面的查询中,如果同一个ID有两个UserNm,它将根据ID复制行。如果ID匹配,我希望两个UserNm和Hrs处于相同的角色(如果可能) 我的结果现在给我的例子Sql server 如何将左连接与一组其他连接一起使用,sql-server,Sql Server,我正在尝试基于EquipWorkOrderID连接两个表。表(设备工单和设备工单) 在下面的查询中,如果同一个ID有两个UserNm,它将根据ID复制行。如果ID匹配,我希望两个UserNm和Hrs处于相同的角色(如果可能) 我的结果现在给我的例子 EquipWorkOrderID/Equip/Description/Resolution/UserNm/Hrs --------------------------------------------------------- 1
EquipWorkOrderID/Equip/Description/Resolution/UserNm/Hrs
---------------------------------------------------------
1 / ForkLift / Bad /Fixed/John Doe / 2
1 /Forklift / Bad /Fixed/Jane Doe /2
我想看什么
EquipWorkOrderID/Equip/Description/Resolution/UserNm1/Hrs1/UserNm2/Hrs2
---------------------------------------------------------
1 / ForkLift / Bad /Fixed/John Doe / 2 / Jane Doe / 2
我已将您的查询结果放入一个表(
selection
)中,并在(cte
)中从中检索数据。用查询替换CTE的内容,并添加我创建的两个新列(UsrNum
和HrsNum
)
我的解决方案使用一个double(一个用于UserNm
列,另一个用于Hrs
列),后跟一个分组。这可能并不理想,但它完成了任务
下面是一个示例,演示如何构建解决方案
样本数据
这只是重新创建当前查询的结果
create table selection
(
EquipWorkOrderID int,
Equip nvarchar(10),
Description nvarchar(10),
Resolution nvarchar(10),
UserNm nvarchar(10),
Hrs int
);
insert into selection (EquipWorkOrderID,Equip,Description,Resolution,UserNm,Hrs) values
(1, 'ForkLift', 'Bad', 'Fixed', 'John Doe', 2),
(1, 'Forklift', 'Bad', 'Fixed', 'Jane Doe', 2);
解决方案
用查询替换CTE的第一部分,并添加两个新列
with cte as
(
select EquipWorkOrderID,Equip,Description,Resolution,UserNm,Hrs,
'Usr' + convert(nvarchar(10),row_number() over(partition by Equip order by UserNm)) as 'UsrNum',
'Hrs' + convert(nvarchar(10),row_number() over(partition by Equip order by UserNm)) as 'HrsNum'
from selection
)
select ph.EquipWorkOrderId, ph.Equip, ph.Description, ph.Resolution,
max(ph.Usr1) as 'UserNm1',
max(ph.Hrs1) as 'Hrs1',
max(ph.Usr2) as 'UserNm2',
max(ph.Hrs2) as 'Hrs2'
from cte c
pivot (max(c.UserNm) for c.UsrNum in ([Usr1], [Usr2])) pu
pivot (max(pu.Hrs) for pu.HrsNum in ([Hrs1], [Hrs2])) ph
group by ph.EquipWorkOrderId, ph.Equip, ph.Description, ph.Resolution;
结果
结果是这样的janedoe
是UserNm1
,因为这就是新的UserNum
列的构造方式(orderbyusernm
)。如果您需要约翰·多伊保持第一,请按调整顺序
EquipWorkOrderId Equip Description Resolution UserNm1 Hrs1 UserNm2 Hrs2
----------------- --------- ------------ ----------- --------- ----- -------- -----
1 ForkLift Bad Fixed Jane Doe 2 John Doe 2
编辑:与原始查询合并的解决方案(未测试)
编辑2:如何使用pivot
Select pivot_table.*
From
(
Select a.EquipWorkOrderID,
b.Hrs,
c.UserNm,
'Tech' + convert(nvarchar(10), row_number() over(order by c.UserNm)) -- construct _generic_ names
From EquipWorkOrder a
Left Join EquipWorkOrderHrs b
On a.EquipWorkOrderID = b.EquipWorkOrderID
Left Join AppUser c
On c.UserID = b.UserID
) t
/*
Pivot (Count(Hrs) For UserNm IN ([Tech1], [Tech2], [Tech3], [Tech4], [Tech5])) AS pivot_table -- UserNm does not contain values like "Tech1" or "Tech2"
*/
Pivot (Count(Hrs) For GenUserNm IN ([Tech1], [Tech2], [Tech3], [Tech4], [Tech5])) AS pivot_table -- pivot over the _generic_ names
你的标题问题有什么关系?你没有使用左连接。。。您使用的是旧式内部联接,不应再使用。您应该使用显式联接。我正在尝试找出如何将左联接与旧式内部联接或其他方式一起使用。将行值(John Doe、Jane Doe)转换为列(UserNm1、UserNm2)称为数据的“旋转”。语法和示例可以在中找到。@sander我查看了文档,但仍然不确定如何将其添加到当前查询中。添加了一个可能的答案,一定要看看它是如何工作的。尝试了解如何添加原始查询。每次添加时,它都会给我一个错误,并且不会运行查询。我将您的原始查询与我的解决方案合并。我没有对此进行测试,因为这样我就必须重新创建所有表。我还将旧样式的联接修改为当前样式,并使用了有意义的表别名。我用新联接格式编辑了原始查询。当我运行查询Sander时,它会给我一个错误。透视分组列必须是可比较的。“说明”列的类型为“文本”,这不是可比较的数据类型text
似乎是。在最后的select
和group by
中,尝试将ph.Description
替换为convert(nvarchar(100),ph.Description)
。喜欢
with cte as
(
SELECT TOP 1000
--Start original selection field list
ewo.EquipWorkOrderID,
ewo.DateTm,
equ.Equip,
equ.AccountCode,
equ.Descr,
ewo.Description,
ewo.Resolution,
sta.Status,
au.UserNm,
ewoh.Hrs,
cat.Category,
ml.MaintLoc,
equt.EquipType,
cre.Crew,
ewo.MeterReading,
typ.Type,
--Added two new fields
'Usr' + convert(nvarchar(10),row_number() over(partition by Equip order by UserNm)) as 'UsrNum',
'Hrs' + convert(nvarchar(10),row_number() over(partition by Equip order by UserNm)) as 'HrsNum'
FROM EquipWorkOrder ewo
JOIN EquipWorkOrderHrs ewoh
ON ewo.EquipWorkOrderID = ewoh.EquipWorkOrderID
JOIN AppUser au
ON au.UserID = ewoh.UserID
JOIN Category cat
ON cat.CategoryID = ewo.CategoryID
JOIN Crew cre
ON cre.CrewID = ewo.CrewID
JOIN Equipment equ
ON equ.EquipmentID = ewo.EquipmentID
JOIN Status sta
ON sta.StatusID = ewo.StatusID
JOIN PlantLoc pll
ON pll.PlantLocID = ewo.PlantLocID
JOIN MaintLocation ml
ON ml.MaintLocationID = ewo.MaintLocationID
JOIN EquipType equt
ON equt.EquipTypeID = ewo.EquipTypeID
JOIN Type typ
ON typ.TypeID = equ.TypeID
ORDER BY ewo.DateTm DESC
)
select ph.EquipWorkOrderId, ph.Equip, ph.Description, ph.Resolution,
max(ph.Usr1) as 'UserNm1',
max(ph.Hrs1) as 'Hrs1',
max(ph.Usr2) as 'UserNm2',
max(ph.Hrs2) as 'Hrs2'
from cte c
pivot (max(c.UserNm) for c.UsrNum in ([Usr1], [Usr2])) pu
pivot (max(pu.Hrs) for pu.HrsNum in ([Hrs1], [Hrs2])) ph
group by ph.EquipWorkOrderId, ph.Equip, ph.Description, ph.Resolution;
Select pivot_table.*
From
(
Select a.EquipWorkOrderID,
b.Hrs,
c.UserNm,
'Tech' + convert(nvarchar(10), row_number() over(order by c.UserNm)) -- construct _generic_ names
From EquipWorkOrder a
Left Join EquipWorkOrderHrs b
On a.EquipWorkOrderID = b.EquipWorkOrderID
Left Join AppUser c
On c.UserID = b.UserID
) t
/*
Pivot (Count(Hrs) For UserNm IN ([Tech1], [Tech2], [Tech3], [Tech4], [Tech5])) AS pivot_table -- UserNm does not contain values like "Tech1" or "Tech2"
*/
Pivot (Count(Hrs) For GenUserNm IN ([Tech1], [Tech2], [Tech3], [Tech4], [Tech5])) AS pivot_table -- pivot over the _generic_ names