3表SQL查询,每个对象一行

时间:2013-06-07 19:06:21

标签: sql database oracle

我必须查询一个数据库,其中对象在一个表中,第二个表中这些对象的属性,以及这些属性的值在第三个表中。愚蠢,我知道。

表格信息(无论如何都是基础知识)

OBJECT -- obj_id, name
ATTRIBUTE -- att_id, name
VALUE -- obj_id, att_id, value

我想要一个查询,其中每个对象的属性出现在我的结果的顶部,并且为每个对象填充这些属性的值。起初我认为一个简单的2内连接查询可以工作,但这会给我一个每个对象的每个属性的结果,而我希望每个对象都是它自己的行。

我的第二个想法是,我将不得不创建一个基本上合并OBJECTATTRIBUTE表的临时表,然后INSERT来自 VALUE的信息表格,然后在新的临时表格上使用非常简单的查询。

想想我先在这里发布这个以获得其他想法和观点。

1 个答案:

答案 0 :(得分:1)

您可以通过遍历属性表来编写构建动态SQL字符串的过程。这是你可以在没有对属性名称进行硬编码的情况下实现这一目标的唯一方法。

如果你不介意对属性名称进行硬编码,有两种方法可以解决它

简单子查询:(稍微容易阅读和理解)

SELECT
    o.name,
    (SELECT value FROM Value v JOIN Attribute a ON v.att_id = a.att_id WHERE a.name = 'Attribute1' and v.obj_id = o.obj_id) [Attribute1],
    (SELECT value FROM Value v JOIN Attribute a ON v.att_id = a.att_id WHERE a.name = 'Attribute2' and v.obj_id = o.obj_id) [Attribute2]
    --etc...
FROM
    [Object] o;

或使用PIVOT:(可能更快一点)

WITH CTE AS (
SELECT 
    o.name ObjectName, 
    a.name AttributeName, 
    v.value AttributeValue
FROM
    [Object] o
    JOIN Value v ON v.obj_id = o.obj_id
    JOIN Attribute a ON a.att_id = v.att_id
)
SELECT
    ObjectName,
    [Attribute1],
    [Attribute2]
    --etc
FROM
    CTE
PIVOT
(
    MAX(AttributeValue)
    FOR AttributeName IN ([Attribute1],[Attribute2])
) as Results;

在这些示例中,“Attribute1”和“Attribute2”是“属性”表中名称列中的属性名称。

如果您确实想构建一个动态查询来处理任意属性(如果您不能硬编码),那么您仍然会使用这些方法之一作为该动态查询的模板。在那种情况下,使用PIVOT方法会更加简单。