【问题标题】:Using the ROLLUP function in CASE Statement在 CASE 语句中使用 ROLLUP 函数
【发布时间】:2018-07-18 19:35:31
【问题描述】:

我有一个查询需要动态更改我执行ROLLUPon 的列。
所以这里是示例数据:

+-----------+---------+-------+--------+-------+----------------------------+
|Location_ID|PLANT    |  ...  |COUNT_IO|TIME_IO|TIME_TARGET_OEE_100_FILTERED|
+-----------+---------+-------+--------+-------+----------------------------+
|01105123000|1        |  ...  |10      |50     |75                          |
+-----------+---------+-------+--------+-------+----------------------------+
|01105123001|1        |  ...  |13      |65     |75                          |      
+-----------+---------+-------+--------+-------+----------------------------+
|01105123002|1        |  ...  |15      |75     |65                          |
+-----------+---------+-------+--------+-------+----------------------------+
|01105123003|1        |  ...  |13      |65     |75                          |
+-----------+---------+-------+--------+-------+----------------------------+
|01101113001|2        |  ...  |40      |200    |400                         |
+-----------+---------+-------+--------+-------+----------------------------+
|01101113002|2        |  ...  |20      |100    |400                         |
+-----------+---------+-------+--------+-------+----------------------------+

所需的输出(ROLLUPLOCATION_ID):

+-----------+---------+-------+--------+-------+
|Location_ID|PLANT    |  ...  |COUNT_IO|OEE    |
+-----------+---------+-------+--------+-------+
|01105123000|1        |  ...  |10      |66,66  |
+-----------+---------+-------+--------+-------+
|01105123001|1        |  ...  |13      |86,66  |
+-----------+---------+-------+--------+-------+
|01105123002|1        |  ...  |15      |115,38 |
+-----------+---------+-------+--------+-------+
|01105123003|1        |  ...  |13      |86,66  |
+-----------+---------+-------+--------+-------+
|NULL       |1        |  ...  |51      |87,93  |
+-----------+---------+-------+--------+-------+

所需的输出(ROLLUPPLANT):

+-----------+---------+-------+--------+-------+
|Location_ID|PLANT    |  ...  |COUNT_IO|OEE    |
+-----------+---------+-------+--------+-------+
|01105123000|1        |  ...  |51      |87,93  |
+-----------+---------+-------+--------+-------+
|01105123001|1        |  ...  |51      |87,93  |
+-----------+---------+-------+--------+-------+
|01105123002|1        |  ...  |51      |87,93  |
+-----------+---------+-------+--------+-------+
|01105123003|1        |  ...  |51      |87,93  |
+-----------+---------+-------+--------+-------+
|01101113001|2        |  ...  |60      |37,5   |
+-----------+---------+-------+--------+-------+
|01101113002|2        |  ...  |60      |37,5   |
+-----------+---------+-------+--------+-------+
|...        |NULL     |  ...  |111     |50,92  |
+-----------+---------+-------+--------+-------+

示例代码:

SELECT
--Dimensions:
  --VALUES_FOR_TABLEAU_METADATA:
    DISTINCT LOCATION_ID,
    CONTINENT, 
    COUNTRY, 
    PLANT,
    BUSINESS_UNIT, 
    PRODUCT,
--Measures (KPI's):
  --Count:
    CASE 
        WHEN <Parameters.BU> = '%' AND <Parameters.Plant> = '%' THEN SUM(COUNT_IO) OVER (PARTITION BY BUSINESS_UNIT)
        WHEN <Parameters.BU> != '%' AND <Parameters.Plant> = '%' THEN SUM(COUNT_IO) OVER (PARTITION BY PLANT)
        ELSE SUM(COUNT_IO) OVER (PARTITION BY LOCATION_ID)
    END AS "COUNT_IO",
  --OEE:
    CASE 
        WHEN TIME_IO = 0 OR TIME_TARGET_OEE_100 = 0
        THEN 0 
        ELSE 
            CASE 
                WHEN <Parameters.BU> = '%' AND <Parameters.Plant> = '%' THEN SUM(TIME_IO) OVER (PARTITION BY BUSINESS_UNIT) *100/SUM(TIME_TARGET_OEE_100_FILTERED) OVER (PARTITION BY BUSINESS_UNIT)
                WHEN <Parameters.BU> != '%' AND <Parameters.Plant> = '%' THEN SUM(TIME_IO) OVER (PARTITION BY PLANT) *100/SUM(TIME_TARGET_OEE_100_FILTERED) OVER (PARTITION BY PLANT)
                ELSE SUM(TIME_IO) OVER (PARTITION BY LOCATION_ID) *100/SUM(TIME_TARGET_OEE_100_FILTERED) OVER (PARTITION BY LOCATION_ID)
            END
    END AS "OEE"
FROM VALUES_FOR_TABLEAU_METADATA
WHERE
  COUNT_TARGET_OEE != 0 AND PLANT LIKE <Parameters.Plant> AND BUSINESS_UNIT LIKE <Parameters.BU> AND LOCATION_ID LIKE <Parameters.LocationID> AND WORKING_DAY BETWEEN <Parameters.WorkingDay_Start> AND <Parameters.WorkingDay_End>
GROUP BY 
    CASE 
        WHEN <Parameters.BU> = '%' AND <Parameters.Plant> = '%' THEN LOCATION_ID
        WHEN <Parameters.BU> != '%' AND <Parameters.Plant> = '%' THEN LOCATION_ID
        ELSE ROLLUP(LOCATION_ID)
    END,
    CASE 
        WHEN <Parameters.BU> = '%' AND <Parameters.Plant> = '%' THEN PLANT
        WHEN <Parameters.BU> != '%' AND <Parameters.Plant> = '%' THEN ROLLUP(PLANT)
        ELSE PLANT
    END,
    CASE 
        WHEN <Parameters.BU> = '%' AND <Parameters.Plant> = '%' THEN ROLLUP(BUSINESS_UNIT)
        WHEN <Parameters.BU> != '%' AND <Parameters.Plant> = '%' THEN BUSINESS_UNIT
        ELSE BUSINESS_UNIT
    END,
    CONTINENT, COUNTRY, PRODUCT, COUNT_IO, COUNT_TARGET_OEE, TIME_IO, TIME_TARGET_OEE_100, TIME_TARGET_OEE_100_FILTERED

我猜这个问题是由CASE 语句中的ROLLUP 引起的,因为直到GROUP BY 的代码工作正常。我也不太确定我的CASE 语句的使用是否正确。

这些参数可能看起来很奇怪,但它们用于 Tableau 并且工作正常。

我得到的错误是:

ORA-00904:“ROLLUP”:标识符无效

【问题讨论】:

  • 向我们展示示例数据集和预期结果。可能有更简单的方法来完成您最终想要实现的目标。
  • @KaushikNayak 抱歉,如果可以理解的话,我花了一段时间添加示例数据...
  • rollup 关键字必须超出case 表达式。
  • @WilliamRobertson 所以没有办法执行动态ROLLUP?
  • 是的,但只能通过编写返回聚合键的case 表达式来允许您想要的汇总,或者通过在比您需要的更多级别上汇总并以某种方式在最后进行过滤。不过,我还没有处理过你复杂的 mcve,所以我无法建议如何做到这一点。

标签: sql oracle case tableau-api rollup


【解决方案1】:

使用 Tableau 的最佳和最简单的方法是让它根据您在 Tableau 中表达的内容生成优化的 SQL。除非在极少数情况下,否则不要将自定义 SQL 与 Tableau 一起使用。通过这种方式,您可以获得更多的灵活性和性能。

在这种情况下,我建议只从 Tableau 连接到 VALUES_FOR_TABLEAU_METADATA。

  1. 定义一个字符串值参数以允许用户为其“汇总”选择维度,例如称为 Dimension_For_Rollup,其中包含两个可能值的列表:“位置”和“工厂”。李>
  2. 定义一个名为Selected_Dimension的计算字段,定义为if [Dimension_For_Rollup] = "Location" then [Location Id] else [Plant] end
  3. 根据需要在您的可视化项上使用 Selected_Dimension。
  4. 显示 Dimension_For_Rollup 的参数控件

因此,用户可以根据需要在汇总维度之间切换,Tableau 将生成优化的 SQL,根据需要缓存查询。

您的 Count_IO 或 Time_IO 统计数据可以在 Tableau 中以不同方式表示,可能需要 Tableau 的详细级别 (LOD) 计算,但同​​样 - 如果您不尝试在 SQL 中对所有内容进行硬编码,您的 Tableau 体验会更好提前。您可以以这种方式使用 Tableau,但您让自己的生活变得艰难,并放弃了很大一部分好处。

【讨论】:

    猜你喜欢
    • 2021-08-26
    • 2022-11-27
    • 2023-02-07
    • 1970-01-01
    • 2017-07-26
    • 1970-01-01
    • 1970-01-01
    • 2015-07-20
    • 2016-05-02
    相关资源
    最近更新 更多