在CASE语句中使用ROLLUP函数

时间:2018-02-08 09:31:13

标签: sql oracle case tableau rollup

我有一个查询,我需要动态更改我执行ROLLUP的列。
所以这是样本数据:

+-----------+---------+-------+--------+-------+----------------------------+
|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                         |
+-----------+---------+-------+--------+-------+----------------------------+

所需的输出(ROLLUP上的LOCATION_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  |
+-----------+---------+-------+--------+-------+

所需的输出(ROLLUP上的PLANT):

+-----------+---------+-------+--------+-------+
|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

我猜这个问题是由ROLLUP语句中的CASE引起的,因为GROUP BY之前的代码运行正常。此外,我不太确定是否正确使用了我的CASE语句。

参数可能看起来很奇怪,但它们可以在Tableau中使用并且工作正常。

我得到的错误是:

  

ORA-00904:&#34; ROLLUP&#34;:无效标识符

1 个答案:

答案 0 :(得分:0)

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

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

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

    因此,用户可以根据需要在Dimension for Rollup之间切换,Tableau将生成优化的SQL,并根据需要缓存查询。

    您的Count_IO或Time_IO统计信息可以在Tableau中以不同方式表示,可能需要Tableau的详细程度(LOD)计算,但同​​样 - 如果您不尝试,您的Tableau体验会更好在SQL中预先硬编码所有内容。你可以以这种方式使用Tableau,但是你会让自己的生活变得艰难并且放弃了很多好处。