将多个自连接转换为 window 函数或子查询 (SQL)
Convert multiple self JOINs to window function or subqueries (SQL)
我有一个包含多个自连接的查询:
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)
这是一个示例 table,我用黄色标记了 where 条件边界内的记录:
这是预期的结果视图:
基本上,我用几个连续的条件过滤一个 table,并将结果显示为 table。
有没有办法,使用 window 函数或子查询将其转换得更快?
您可以通过删除类型转换、向经常查询的适当列添加索引,或者将 4-table 连接替换为 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 子句中的枢轴 w/o 类型转换只用了 17 毫秒,所有 WHERE 子句转换 运行 只用了 20-22 毫秒。
我有一个包含多个自连接的查询:
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)
这是一个示例 table,我用黄色标记了 where 条件边界内的记录:
这是预期的结果视图:
基本上,我用几个连续的条件过滤一个 table,并将结果显示为 table。
有没有办法,使用 window 函数或子查询将其转换得更快?
您可以通过删除类型转换、向经常查询的适当列添加索引,或者将 4-table 连接替换为 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 子句中的枢轴 w/o 类型转换只用了 17 毫秒,所有 WHERE 子句转换 运行 只用了 20-22 毫秒。