我想知道是否有一种比我想出的更简单的方法来实现我的目标。
我正在返回一个适用于对象的特定属性。对象经历多次迭代,属性可能会从迭代到迭代略有变化。只有属性更改时,才会将迭代添加到表中。因此,最近的迭代可能不在表中。
每个属性由属性ID(AttribId)和Generation ID(GenId)的组合唯一标识。
Object_Table
ObjectId | AttribId | GenId
32 | 2 | 3
33 | 3 | 1
Attribute_Table
AttribId | GenId | AttribDesc
1 | 1 | Text
2 | 1 | Some Text
2 | 2 | Some Different Text
3 | 1 | Other Text
当我查询特定对象时,如果可能,我希望它返回完全匹配。例如,对象ID 33将返回“其他文本”。
但如果没有完全匹配,我希望返回最新一代(最大的生成ID)。例如,对象ID 32将返回“Some Different Text”。由于Gen 3中没有属性ID 2,因此它使用属性为Gen ID 2的最新迭代中的描述。
这是我为实现这一目标而想出的:
SELECT attr.AttribDesc
FROM Attribute_Table AS attr
JOIN Object_Table AS obj
ON obj.AttribId = obj.AttribId
WHERE attr.GenId = (SELECT MIN(GenId)
FROM(SELECT CASE obj2.GenId
WHEN attr2.GenId THEN attr2.GenId
ELSE(SELECT MAX(attr3.GenId)
FROM Attribute_Table AS attr3
JOIN Object_Table AS obj3
ON obj3.AttribId = attr3.AttribId
WHERE obj3.AttribId = 2
)
END AS GenId
FROM Attribute_Table AS attr2
JOIN Object_Table AS obj2
ON attr2.AttribId = obj2.AttribId
WHERE obj2.AttribId = 2
) AS ListOfGens
)
有没有更简单的方法来实现这一目标?我觉得应该有,但我对SQL比较陌生,不能想到别的什么。
谢谢!
答案 0 :(得分:2)
以下查询将返回匹配值(如果找到),否则使用相关子查询返回具有最高GenId且匹配AttribId的值:
SELECT obj.Object_Id,
CASE WHEN attr1.AttribDesc IS NOT NULL THEN attr1.AttribDesc ELSE attr2.AttribDesc END AS AttribDesc
FROM Object_Table AS obj
LEFT JOIN Attribute_Table AS attr1
ON attr1.AttribId = obj.AttribId AND attr1.GenId = obj.GenId
LEFT JOIN Attribute_Table AS attr2
ON attr2.AttribId = obj.AttribId AND attr2.GenId = (
SELECT max(GenId)
FROM Attribute_Table AS attr3
WHERE attr3.AttribId = obj.AttribId)
如果给定的AttribId根本没有匹配的记录,它将返回NULL。如果你想在这种情况下根本没有记录,那么让第二个JOIN成为INNER JOIN而不是LEFT JOIN。
答案 1 :(得分:0)
试试这个......
如果逻辑找不到 Object_table GENID 的匹配项,则会将其映射到{ON
子句中的下一个最高GENID 1}}。
JOIN
答案 2 :(得分:0)
这应该有效:
with x as (
select *, row_number() over (partition by AttribId order by GenId desc) as rn
from Attribute_Table
)
select isnull(a.attribdesc, x.attribdesc)
from Object_Table o
left join Attribute_Table a
on o.AttribId = a.AttribId and o.GenId = a.GenId
left join x on o.AttribId = x.AttribId and rn = 1