【问题标题】:How to use Oracle CTE for such query?如何使用 Oracle CTE 进行此类查询?
【发布时间】:2013-02-20 15:54:43
【问题描述】:

我的查询如下所示:

SELECT m.Name, (m.Value + NVL(a1.Value1, 0) + NVL(a2.Value2,0) + NVL(a3.Value3,0) "Value"
FROM m MainTable
LEFT JOIN Additional1 a1 ON (...)
LEFT JOIN Additional2 a2 ON (...)
LEFT JOIN Additional3 a3 ON (...)
WHERE (conditions on m)
ORDER BY 1;

这些查询为每个Name 生成多个行。

我需要使用以下逻辑将每个 Name 限制为 一个 行:包括 Value 最接近给定 Name 的平均值的行。

有些事情告诉我,CTE 应该允许更紧凑的代码并希望实现更有效的实现,因此我不需要多次重复几乎相同的查询。

你能指出我正确的方向吗?

【问题讨论】:

    标签: sql oracle11g common-table-expression


    【解决方案1】:

    CTE 可以提供帮助,但我认为关键是分析功能。首先,您可以使用分析函数计算每个名称的平均值。然后你可以对差值的绝对值进行排名。

    这是带有 CTE 的版本:

    with t as (
        SELECT m.Name,
               (m.Value + NVL(a1.Value1, 0) + NVL(a2.Value2,0) + NVL(a3.Value3,0) "Value"
        FROM m MainTable
             LEFT JOIN Additional1 a1 ON (...)
             LEFT JOIN Additional2 a2 ON (...)
             LEFT JOIN Additional3 a3 ON (...)
       WHERE (conditions on m)
    )
    select t.*
    from (select t.*,
                 row_number() over (partition by name order by avgdiff) as seqnum
          from (select t.*,
                       abs(value - avg(value) over (partition by name)) as AvgDiff
                from t
               ) t
         ) t
    where seqnum = 1
    

    【讨论】:

    • 我在这里有点困惑。为什么“外部”查询和两个内部查询都具有相同的别名?
    猜你喜欢
    • 2020-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-18
    • 2014-09-02
    • 2013-05-15
    相关资源
    最近更新 更多