【问题标题】:Alternative to executing Netezza SQL subquery multiple times in Case When?在 Case When 中多次执行 Netezza SQL 子查询的替代方案?
【发布时间】:2019-06-18 17:20:47
【问题描述】:
SELECT DISTINCT lr.id, 
       lr.dept,
       lr.name
       Case When lr.id IN (SELECT id FROM RESULTS WHERE PANEL_FLAG LIKE '%value1%') AND lr.id IN (SELECT id FROM RESULTS WHERE PANEL_FLAG LIKE '%value2%') Then 1
            Else 0
            End As both_panels,
       Case When lr.id IN (SELECT id FROM RESULTS WHERE PANEL_FLAG LIKE '%value1%') AND lr.id NOT IN (SELECT id FROM RESULTS WHERE PANEL_FLAG LIKE '%value2%') Then 1
            Else 0
            End As only_value1_panel,
  FROM RESULTS lr

我已经简化了这一点,实际上我实际上需要更多的 Case When 语句,这是性能的噩梦,因为子查询每次都会执行。有没有更高效的方法来做到这一点?

我尝试在查询之前创建公用表表达式和临时表,但我这样做的方式(用 CTE 或临时表中的 SELECT 替换子查询语句)似乎没有产生任何性能差异,因为它每次仍在执行查询。

【问题讨论】:

    标签: sql performance netezza


    【解决方案1】:

    这通常使用条件聚合来处理。我认为这符合您的逻辑:

    SELECT lr.id, lr.dept, lr.name,
           LEAST(MAX(Case When PANEL_FLAG LIKE '%value1%' THEN 1 ELSE 0 END),
                 MAX(Case When PANEL_FLAG LIKE '%value2%' THEN 1 ELSE 0 END)
                 ) As both_panels,
           LEAST(MAX(Case When PANEL_FLAG LIKE '%value1%' THEN 1 ELSE 0 END),
                 MAX(Case When PANEL_FLAG LIKE '%value2%' THEN 0 ELSE 1 END)
                 ) as only_value1_panel,
    FROM RESULTS lr
    GROUP BY lr.id, lr.dept, lr.name
    

    【讨论】:

      【解决方案2】:

      如果“in”列表的子查询带有“常量”where子句,我会考虑将它们填充到脚本中(逗号和所有),然后将它们注入“sql模板”文件并运行它。 那将运行得非常快。 当然,生成的列表应该相当小(所有列表总共小于 60KB),否则 sql 语句会变得太大。

      【讨论】:

        猜你喜欢
        • 2020-08-17
        • 1970-01-01
        • 1970-01-01
        • 2015-08-23
        • 1970-01-01
        • 2017-05-30
        • 1970-01-01
        • 1970-01-01
        • 2017-08-15
        相关资源
        最近更新 更多