SQL中的函数与复杂连接

SQL中的函数与复杂连接,sql,function,join,Sql,Function,Join,一次又一次地使用多个表的复杂联接,而不是同时使用scaler和table值函数,这是一种好的做法。 比如说 案例1: SELECT * FROM table1 t1 INNER JOIN table2 t2 ON t1.ID=t2.ID INNER JOIN table2 t3 ON t2.ID=t3.ID INNER JOIN table2 t4 ON t3.ID=t4.ID INNER JOIN table2 t5 ON t4.ID=t5.ID INNER JOIN table2 t6 O

一次又一次地使用多个表的复杂联接,而不是同时使用scaler和table值函数,这是一种好的做法。 比如说

案例1:

SELECT 
*
FROM table1 t1
INNER JOIN table2 t2 ON t1.ID=t2.ID
INNER JOIN table2 t3 ON t2.ID=t3.ID
INNER JOIN table2 t4 ON t3.ID=t4.ID
INNER JOIN table2 t5 ON t4.ID=t5.ID
INNER JOIN table2 t6 ON t5.ID=t6.ID
INNER JOIN table2 t7 ON t6.ID=t7.ID
案例2

SELECT *
FROM table1 t1
INNER JOIN udf_myFunc() udf ON udf.ID=t1.ID

在某些情况下,一种方法有一定的优势吗?

对于可读性,1更好-对象正在做什么很清楚,尽管它更详细

对于重用,2更好—特别是如果您看到逻辑可能在多个调用之间发生变化,最好只在一个地方进行更改

我想这取决于你的目标是什么。我通常选择可读性而不是重复使用

如果要隐藏/管理复杂性并启用重用,请使用视图 在联接中使用UDF不会提高性能 您可能需要设置索引视图-这可能会提高性能 在MS SQL中,自定义项很难组织和管理。过分依赖它们可能很快就会导致一堆UDF
我必须投票反对职能方向。如果没有其他原因,它会混淆意图。此外,虽然如果重用它可能会节省一些工作,但这是唯一可能的好处,因为它不会提高性能

我喜欢在需要处理特定数据段时使用函数,但使用函数避免连接是一种令人讨厌的处理方式。

这取决于具体情况

与连接相比,多语句表值函数是性能杀手。它不能展开并集成到查询中。在应用中使用时特别糟糕。 然而,有时这是一种好处,因为一个产生相同结果的连接是一场噩梦。 内联表值函数可以。服务器可以将其展开并集成到查询中。性能不会有任何差异,执行计划将与连接相同。 因此,在不降低性能的情况下加入一些逻辑可能是一个不错的选择。 标量函数基本上是好的,除了查询优化程序执行奇怪的操作并开始调用它的次数远远超过它实际应该调用的次数的情况。在这种情况下,可以将此类函数重写为表值函数,该函数返回一行一列,并将其作为表连接,而不是使用where条件中的值。 但除此之外也没关系。
为什么更好?可读性?表演还有别的吗?我也喜欢风景。但函数的关键是它的参数。视图可以被看作是一个参数化函数,因为从外部应用于其where的任何内容都会被处理,就好像where在视图本身中一样。但是当参数在视图内部处于连接条件时,不能从外部传递它。您必须使用函数。Qry第1部分:创建表tempReturnTable EmployeeID BIGINT NULL声明@Cols为VARCHARMAX SELECT@Cols=Coalesce@Cols+'、['+Name+']'、['+Name+']'来自Master_AllowancedEducation MAD,其中ID-1和MAD.ID不在20,25,26,27,29中声明@sql为NVARCHARMAXQry第2部分:选择@sql=Coalesce@Sql+'ALTER TABLE tempReturnTable ADD['+MAd.Name+']VARCHAR100','ALTER TABLE tempReturnTable ADD['+MAd.Name+']VARCHAR100'来自Master_AllowancedEducation MAD,其中MAD.ID-1和MAD.ID不在20,25,26,27,29 PRINT@Sql EXEC@Sql SET@Sql=SET@Sql='选择ESPS.EmployeeID,MAD.Name作为津贴,ESPA.Amount作为金额从Master_AllowancedEducation MADQry第3部分:ESPA.AllowancedEducation ID=MAD.ID和ESPA.bIsActive=1左侧加入ESPS.ID=ESPA.EmployeeStandardPayScaleID和ESPS.bIsActive=1,其中MAD.ID-1和MAD.bOnlyForCalculation=0和MAD.ID不在20,25,26,27,29和ESPS.EmployeeID-1-收集结束,格式开始插入tempReturnTable SELECT*Qry第4部分:从临时t透视汇总到t的金额[容差]在“++@Cols++”p DROP TABLE temp'-PRINT@Sql EXEC@Sql SELECT*FROM tempReturnTable DROP TABLE tempReturnTable我无法使用函数,因为我不知道返回表结构