Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 针对不同的标准在同一个表上多次连接,而不是在聚合表上一次连接_Sql_Sql Server_Join_Optimization_Sql Server 2008 R2 - Fatal编程技术网

Sql 针对不同的标准在同一个表上多次连接,而不是在聚合表上一次连接

Sql 针对不同的标准在同一个表上多次连接,而不是在聚合表上一次连接,sql,sql-server,join,optimization,sql-server-2008-r2,Sql,Sql Server,Join,Optimization,Sql Server 2008 R2,我目前有一个视图,它可以根据相同的条件多次连接一个表,例如: Select m.ID, a.value as value1, b.value as value2, c.value as value3, d.value as value4 from main_table m left join other_table a on m.ID = a.ID and a.X = 'this' left join other_table b on m.ID = b.ID and b.X = 'that'

我目前有一个视图,它可以根据相同的条件多次连接一个表,例如:

Select
m.ID,
a.value as value1,
b.value as value2,
c.value as value3,
d.value as value4

from
main_table m
left join other_table a on m.ID = a.ID and a.X = 'this'
left join other_table b on m.ID = b.ID and b.X = 'that'
left join other table c on m.ID = c.ID and c.X = 'third'
left join other table d on m.ID = d.ID and d.X = 'other'
我想知道,如果将这四个表合并并聚合它们,这样我就可以在一个联接中完成所有操作,效率是高还是低:

Select
m.ID,
value1,
value2,
value3,
value4

from
main_table m
left join (select ID,
           MAX(case X when 'this' then value end) value1,
           MAX(case X when 'that' then value end) value2,
           MAX(case X when 'third' then value end) value3,
           MAX(case X when 'other' then value end) value4
           from ( 
           select ID,X,value from other_table
           where X = 'this'
           union all
           select ID,X,value from other_table
           where X = 'that'
           union all
           select ID,X,value from other_table
           where X = 'third'
           union all
           select ID,X,value from other_table
           where X = 'other')
           GROUP BY ID) AS A
on A.ID = m.ID
在进行实验之前我会问,因为事实上,这个观点要复杂得多,重写要花很长时间,所以我想确保我没有浪费时间

基本上,我的问题是,执行聚合和分组的成本是否会超过执行这些多个联接的成本。此外,我认为应该考虑到这个视图包含许多其他连接(15-20),因此我试图通过任何方式减少该数量来进行优化

编辑此外,我觉得有必要补充一点,即涉及到链接服务器,并且这两个表位于不同的数据库中;我试图减少联接数量的另一个原因

如有任何见解或帮助,将不胜感激


提前感谢。

与大多数性能问题一样,您需要在系统数据上测试不同的版本。但是,我认为您需要的聚合查询是:

Select m.ID, value1, value2, value3, value4
from main_table m left join
     (select ID,
             MAX(case X when 'this' then value end) value1,
             MAX(case X when 'that' then value end) value2,
             MAX(case X when 'third' then value end) value3,
             MAX(case X when 'other' then value end) value4
      from other_table
      group by ID
     ) A
     on A.ID = m.ID;

聚合的优点是,添加更多的值不会对性能产生太大的影响。添加新联接可能会影响性能,因此在某些情况下,聚合可能会优于联接。

根据我的经验,在一个特定的模式设计中,我们将自定义属性及其值存储在一个实体的单独表中,并且当我们必须查询回实体实例的所有自定义属性数据时,我们必须将其联接回同一个表多次

我们有效地使用了
PIVOT
语法来规避多个连接。在你的情况下,这将是这样的

Select
m.ID,
[this],[that],[third],[other]
from
main_table m
left join
    (
        select id,[this],[that],[third],[other]
            (select id, X from other_table )s
                PIVOT
            ( 
                max(value) 
                    for X in ([this],[that],[third],[other])
            )p 
    )t
on t.id=m.id

N.B:请注意,在我们的案例中,通过避免所有的
连接,这导致了巨大的性能提升

查询是不同的,除非您可以保证其他表中的匹配不超过一个。另外,“其他桌子”总是同一张桌子吗?我可能会坚持第一种选择。如果您担心性能,请确保在
X
上有索引。您甚至可以为
X
@GordonLinoff的每个值添加一些过滤索引。这是怎么回事?如果ID在另一个表中不存在,我是否会得到
value
NULL
。我用词不对。我的意思是不超过一个,而不是至少一个。@GordonLinoff yes other_table始终是同一个table+1,因为它确实有效,而且这是我在阅读您的答案后第一次能够使用PIVOT函数。但我接受了另一个答案,因为它更接近于我所使用的,并且因为它接受了我在这个视图的其他部分中需要的多个条件(
MAX(X='this'和…