【问题标题】:Convert multiple self JOINs to window function or subqueries (SQL)将多个 self JOIN 转换为窗口函数或子查询 (SQL)
【发布时间】:2020-11-18 12:19:27
【问题描述】:

我有一个包含多个自连接的查询:

SELECT t2.Name, t2.Date as date, t2.Value as value1, t3.Value as value2, t4.Value as value3
FROM table_t t1
    RIGHT JOIN #tempPredefinedIndicators t2
        ON t1.Name = t2.Name
    JOIN #tempPredefinedIndicators t3 
        ON t2.Name = t3.Name AND t2.Date = t3.Date
    JOIN #tempPredefinedIndicators t4 
        ON t2.Name = t4.Name AND t2.Date = t4.Date    
WHERE t1.ValueName = 'one' AND DATEDIFF(year, ISDATE(t1.Value), GETDATE()) >=10
AND (t2.ValueName = 'two' AND TRY_CONVERT(FLOAT, t2.Value) > 0.15)
AND (t3.ValueName = 'three' AND TRY_CONVERT(FLOAT, t3.Value) BETWEEN 0 AND 0.5)
AND (t4.ValueName = 'four' AND TRY_CONVERT(FLOAT, t4.Value) > 0.15)

这是一个示例表,其中我用黄色标记了 where 条件边界内的记录:

这是预期的结果视图:

基本上我用几个连续的条件过滤一个表,并将结果显示为一个表。

有没有办法,使用窗口函数或子查询将其转换为更快?

【问题讨论】:

标签: sql tsql subquery window-functions self-join


【解决方案1】:

您可以通过删除类型转换、向经常查询的相应列添加索引或将 4 表连接替换为 PIVOT 来提高性能。

SELECT * FROM (
  SELECT
    [name],
    [valuename],
    [value]
  FROM table_t
  WHERE 
    (valuename = 'one' and datediff(year, isdate(value), getdate()) > 10)
     or 
    (valuename = 'two' and TRY_CONVERT(FLOAT, Value) > 0.15)
     or 
    (ValueName = 'three' AND TRY_CONVERT(FLOAT, Value) BETWEEN 0 AND 0.5)
     or
    (ValueName = 'four' AND TRY_CONVERT(FLOAT, Value) > 0.15)
) a
PIVOT (
  MAX([value])
  FOR [valuename]
  IN (
    [one], [two], [three], [four]
  )
) AS PivotTable

在这里通过示例自学:https://www.sqlshack.com/dynamic-pivot-tables-in-sql-server/

您的查询在 sql-fiddle 中运行了 30 毫秒;在 WHERE 子句中运行无类型转换的数据只需要 17 毫秒,而在所有 WHERE 子句转换中运行需要 20-22 毫秒。

【讨论】:

  • 谢谢。这对我来说非常有效,并且是我一直在寻找的简单性,但我在该领域缺乏知识是一个障碍。
猜你喜欢
  • 2023-02-05
  • 2017-07-12
  • 2015-11-14
  • 2020-05-27
  • 2013-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多