查询以在其中一个列值重复时返回唯一值

时间:2013-12-04 10:40:50

标签: sql sql-server oracle oracle11g db2

我有一个像以下

的SQL查询
SELECT Name.Nameguid,Name.Name,relation.ancestorguid,relation.productguid,relation.pathLength
     FROM Name Name 
     JOIN ProductRelationship relation 
       ON Name.productGuid = relation.ancestorGuid 
      AND relation.productGuid = '6075D04A-E74A-464B-94E7-25374F0B9833' 
     ORDER BY relation.pathLength DESC

返回以下内容

NameGuid                                Name                AncestorGuid                            ProductGuid                             PathLength
6D39CB04-88D9-4125-A052-8DF608AAD29C    NameParentOnly  8E07F824-763C-434F-926C-80FCC8690243    6075D04A-E74A-464B-94E7-25374F0B9833    2
186E1DF3-4D1A-4020-B845-1280CF1092EA    NameParentChild 8E07F824-763C-434F-926C-80FCC8690243    6075D04A-E74A-464B-94E7-25374F0B9833    2
CA60E542-4047-4B4D-AA22-0744A1E5F2E0    childlevelName  D9833FCA-93A7-42F5-AFC3-5544F7A4425D    6075D04A-E74A-464B-94E7-25374F0B9833    1
A09D01FC-D69D-4AFA-B4D0-C804F030A281    NameParentChild D9833FCA-93A7-42F5-AFC3-5544F7A4425D    6075D04A-E74A-464B-94E7-25374F0B9833    1
63148C89-59FD-4C96-883F-60E8446A6BC4    NameParentChild 6075D04A-E74A-464B-94E7-25374F0B9833    6075D04A-E74A-464B-94E7-25374F0B9833    0

我的场景是这样的,当name gets repeated时,我希望查询只返回路径长度值最小的行。

在上面的示例中,只有NameParentChild重复三次,我希望它返回路径长度最短的一个(在这种情况下为零)

以下是我期待的结果

NameGuid                                Name                AncestorGuid                            ProductGuid                             PathLength
6D39CB04-88D9-4125-A052-8DF608AAD29C    NameParentOnly  8E07F824-763C-434F-926C-80FCC8690243    6075D04A-E74A-464B-94E7-25374F0B9833    2
CA60E542-4047-4B4D-AA22-0744A1E5F2E0    childlevelName  D9833FCA-93A7-42F5-AFC3-5544F7A4425D    6075D04A-E74A-464B-94E7-25374F0B9833    1
63148C89-59FD-4C96-883F-60E8446A6BC4    NameParentChild 6075D04A-E74A-464B-94E7-25374F0B9833    6075D04A-E74A-464B-94E7-25374F0B9833    0

我如何调整查询来执行此操作?我希望查询也适用于Oracle,DB2和SQL服务器。

由于

1 个答案:

答案 0 :(得分:2)

您应该可以使用analytic (or window) functions执行此操作。分析函数是否在您的RDBMS中可用,以及您必须使用哪种语法是另一回事。在Oracle中,假设NameGuid对于您的原始查询是唯一的,您可以这样做:

select NameGuid, Name, AncestorGuid, ProductGuid, PathLength
from (
    select 
    NameGuid, 
    Name, 
    AncestorGuid, 
    ProductGuid, 
    PathLength, 
    -- take every row from original query with the same Name as this,
    -- order those rows by PathLength (and NameGuid to disambiguate)
    -- and return the NameGuid of the first row in that "partition"
    first_value(NameGuid) over (partition by Name order by PathLength asc, NameGuid asc) MinNameGuid
    from ( 
        ... your original query ...
    )
)
where 
-- return rows whose NameGuid is the same as the NameGuid calculated by first_value(...)
NameGuid = MinNameGuid