2015-12-18 83 views
1

我具有可以或可以不具有取决于是否就是已被销售的所有者的设备实体:检查存在

DEVICE 
====== 
Id 
OwnerId (null) 
DeviceTypeId (not null) 

Owner 
===== 
Id 
Name 

每种类型的设备都可以有不同的能力,而每个功能都可以映射到多个类型,所以我有一个联结表。

DeviceType 
==== 
Id 
ModelNum 

Capability 
========== 
Id 
CapabilityName 

Type_Capability 
=============== 
Id 
DeviceTypeId 
CapabilityId 

我想编写一个查询,如果它存在,将返回该设备的所有者,以及设备是否有名为“超频”的能力。

我有以下几点:

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

请准备http://sqlfiddle.com样本数据和所需的输出。提供准确答案并避免猜测会容易得多。 – lad2025

回答

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。

+0

工程像一个魅力,但我承认我不太明白如何。我发现我们正在拼凑聚合,但SUM和'CASE'的内幕是什么?我们在分组过程中评估每条记录? –

+0

@MisterEpic。 。 。它正在用“超频”值来计算功能的数量。 '> 0'只是说有一些。这可以在'on'子句中,但是这种方法可以更容易地推广到更多功能。 –

1

你想使用一个左外连接 - 并在on子句中添加功能名称'overclock'。然后,使用case语句来确定该记录是否存在 - 并在其返回时返回“是”,否则返回“否”。另外,我缩进查询为清楚:

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子句影响结果集的唯一时间。

编辑:

因为你的数据库的结构,我认为这是最好只使用下面的查询。因为“超频” 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

每个功能都有一条记录回来。当我回到我的办公室时,我会创作一个小提琴。谢谢! –

+0

@MisterEpic好的,我更新了答案。在创建小提琴之前尝试一下 - 我认为它会起作用。 –