我有一个设备实体,根据是否已售出,可能有也可能没有拥有者:
DEVICE
======
Id
OwnerId (null)
DeviceTypeId (not null)
Owner
=====
Id
Name
每种类型的设备都可以具有不同的功能,而每种功能都可以映射到多种类型,因此我有一个联结表。
DeviceType
====
Id
ModelNum
Capability
==========
Id
CapabilityName
Type_Capability
===============
Id
DeviceTypeId
CapabilityId
我想写一个查询,如果它存在,将返回设备的所有者,以及设备是否具有名称" overclock"的能力。
我有以下内容:
SELECT device.Id, owner.Name, ??? as [hasOverclock]
FROM Device device
LEFT OUTER JOIN Owner owner on owner.Id = device.ownerId
INNER JOIN DeviceType deviceType on deviceType.Id = device.DeviceTypeId
INNER JOIN TypeCapability typeCapability on typeCapability.DeviceTypeId = deviceType.Id
INNER JOIN Capability capability on capability.Id = typeCapability.CapabilityId
WHERE device.Id = 100;
我不确定如何在我的投影中显示设备是否超频。
答案 0 :(得分:1)
您想使用左外连接 - 并在on子句中添加功能名称' overclock'。然后,使用案例陈述来确定该记录是否存在 - 并返回'是'当它发生的时候 - 并且'否'因为它什么时候没有。另外,为了清晰起见,我缩进了您的查询:
SELECT device.Id,
owner.Name,
CASE
WHEN Capability.ID IS NULL THEN 'NO'
ELSE 'YES'
END as [hasOverclock]
FROM Device device
LEFT OUTER JOIN Owner
on Owner.Id = Device.ownerId
INNER JOIN DeviceType
on DeviceType.Id = Device.DeviceTypeId
INNER JOIN TypeCapability
on TypeCapability.DeviceTypeId = DeviceType.Id
LEFT OUTER JOIN Capability
on Capability.Id = TypeCapability.CapabilityId
AND Capability.CapabilityName = 'Overclock'
WHERE device.Id = 100;
请告知我这是否有效,我会编辑我的答案。
注意:您需要在ON子句中保持功能名称检查(对于'超频')而不是在where子句中。如果它在where子句中,则您将省略完全不加入的记录(这与使用内部联接相同)。外连接是唯一一次将条件从where子句移动到on子句会影响结果集。
修改强>
由于数据库的结构,我认为最好只使用以下查询。由于' OverClock' capabilityID不会改变 - 因为您的查询特定于此值,我认为在查询中使用它更有意义,使其更简单:
DECLARE @OverClockCapabilityID int = 55
SELECT D.Id as [DeviceID],
O.Name as [OwnerName],
CASE
WHEN TC.ID IS NULL THEN 'NO'
ELSE 'YES'
END AS [HasOverClock]
FROM Device D //Should only be one record
JOIN DeviceType DT //Should only be one record
ON D.DeviceTypeID = DT.ID
LEFT OUTER JOIN Type_Capability TC //Should only be one record, assuming you don't have duplicate records in this join table (which you shouldn't)
ON DT.ID = TC.DeviceTypeID
AND TC.CapabilityID = @OverClockCapabilityID //This eliminates other capabilities, which we don't care about in this query
LEFT OUTER JOIN Owner O
ON D.OwnerID = O.ID
我希望这适合你!
答案 1 :(得分:1)
您需要汇总:
SELECT D.ID as DeviceID, O.Name as OwnerName,
(CASE WHEN SUM(CASE WHEN C.CapabilityName = 'overclock' THEN 1 ELSE 0 END) > 0
THEN 1
ELSE 0
END) as OverclockFlag
FROM Device D JOIN DeviceType
DT
ON D.DeviceTypeID = DT.ID LEFT OUTER JOIN
Type_Capability TC
ON DT.ID = TC.DeviceTypeID LEFT OUTER JOIN
Capability C
ON TC.CapabilityID = C.ID LEFT OUTER JOIN
Owner O
ON D.OwnerID = O.ID
WHERE Device.ID = 100
GROUP BY D.ID, O.Name ;
请注意,您要删除where
并为所有设备ID执行此操作。