【问题标题】:Using sub-query in FROM instead of WHERE - SAP BO Web Intelligence在 FROM 中使用子查询而不是 WHERE - SAP BO Web Intelligence
【发布时间】:2019-04-18 10:11:21
【问题描述】:

我正在尝试使用 WebI 查询生成器来实现一些我已经可以通过编写纯 SQL 查询来实现的目标。

要求:相对于通过该组的所有票,计算特定组花费超过某个任意时间限制将票转移到任何二线组的票的百分比。

为了实现这一点,我从审计表中选择特定的行并使用 T-SQL LAG() 函数来获取上一个组更改的时间(在 Universe 中已经有一个对象)。由于 LAG() 的工作方式,我选择所有组更改行(和创建条目)作为中间结果,以便能够计算票在任何组中的时间(ticket = '...' 只是为了限制开发过程中的执行时间):

SELECT 
    ticket,
    change_date,
    LAG(change_date) OVER (PARTITION BY ticket ORDER BY change_date) 'change_date_prev',
    CASE
        WHEN LAG(change_date) OVER (PARTITION BY ticket ORDER BY change_date) IS NULL THEN 0
        ELSE change_date-LAG(change_date) OVER (PARTITION BY ticket ORDER BY change_date)
    END AS duration,
    group_before,
    group_after
FROM audit_log
WHERE 
    ticket = 'cr:2792293'
    AND (
        aud_opr = 'create'
        OR changed_attr ='group'
    )

结果如下:

ticket      change_date  change_date_prev  duration     group_before  group_after
------      -----------  ----------------  --------     ------------  -----------
cr:2792293  1554802730   NULL              0
cr:2792293  1554802808   1554802730        78           SUP-GroupA    OtherGroupA
cr:2792293  1554805870   1554802808        3062         OtherGroupA   OtherGroupB
cr:2792293  1554806322   1554805870        452          OtherGroupB   OtherGroupC
cr:2792293  1555319896   1554806322        513574       OtherGroupC   SUP-GroupA
cr:2792293  1555341997   1555319896        22101        SUP-GroupA    OtherGroupA
cr:2792293  1555343530   1555341997        1533         OtherGroupA   SUP-GroupA
cr:2792293  1555343625   1555343530        95           SUP-GroupA    SUP-GroupB
cr:2792293  1555344681   1555343625        1056         SUP-GroupB    OtherGroupA
cr:2792293  1555346162   1555344681        1481         OtherGroupA   SUP-GroupA
cr:2792293  1555346629   1555346162        467          SUP-GroupA    OtherGroupB
cr:2792293  1555346961   1555346629        332          OtherGroupB   OtherGroupC
cr:2792293  1555417764   1555346961        70803        OtherGroupC   SUP-GroupA
cr:2792293  1555419234   1555417764        1470         SUP-GroupA    SUP-GroupC
cr:2792293  1555424241   1555419234        5007         SUP-GroupC    SUP-GroupA
cr:2792293  1555513936   1555424241        89695        SUP-GroupA    SUP-GroupC

现在,我需要优化这个结果集,给我两个数字:

  1. group_before 是 SUP-GroupA 的工单计数。在纯 SQL 上,我会使用基本查询作为 FROM 部分的子查询,就像这样(需要报告可视化的其余列),然后只计算报告上的票:
SELECT
    *
FROM ( <base query> ) AS transfers
WHERE
    transfers.group_before = 'SUP-GroupA'
  1. group_before 是 SUP-GroupA、group_after 是其他某个 SUP-* 组且持续时间大于某个任意值的工单计数(同样,将计数留给报告):
SELECT
    *
FROM ( <base query> ) AS transfers
WHERE
    transfers.group_before = 'SUP-GroupA'
    AND transfers.group_after LIKE 'SUP-%'
    AND transfers.duration > 1234

这些查询在对 DB 执行时完美运行,但无论我在 Web Intelligence 和 Universe 中尝试什么魔法,我都无法让查询生成器生成类似的查询。我所知道的 WebI 的子查询功能都会对 WHERE 子句进行子查询,但这对我不起作用,因为 LAG() 函数适用于返回的结果集的行,所以如果我过滤它们change_date_prev 的平面查询将从上一个返回的行中获取change_date,而不是从上一个组更改中获取。

我知道通过在查询构建器的查询脚本查看器中手动编写查询来解决这个问题是一种肮脏的方法,但我会尽量避免这种情况,因为如果有人甚至查看查询,手动查询就会被覆盖稍后生成器。

我是否达到了 Web Intelligence 的极限,或者有没有办法绕过这个问题而无需对宇宙中的大量一次性对象进行硬编码?

【问题讨论】:

    标签: business-objects


    【解决方案1】:

    我相信您已经想到了这一点,但为什么不在报告中进行这些计算呢?您可以保持原样查询,然后使用过滤器和变量来获得最终结果。

    如果这不可行,那么我认为唯一的其他选择是在 Universe 中创建派生表。您必须在 ticket 上添加 GROUP BY(以及可能在条件下使用的任何其他字段)以保持 LAG 正常工作。

    【讨论】:

    • 我试过了,但事实上,一张票可以有多次违规转移,并且仍然算作我正在计算的 KPI 的一次违规(违规票与票总数的比率)已经呈现我以前的尝试没有结果。这一切都归结为如何在报告中完成聚合,因此将每个违规转移标记为基本查询给我留下了如何计算违规票数而不是违规数本身的问题。
    • 那么派生表选项可能是更好的解决方案。
    • 我已经接受了这个答案作为解决方案,我最终用派生表来做。与我最大的恐惧相反,为所有组更改获取change_date_prev 的性能令人惊讶 - 大约 37 秒用于约 370 万个条目,然后可以与其他组过滤器的任何组合一起使用。感谢您的时间和建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多