Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.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
使用union和具有视图的列的SQL Server查询_Sql_Sql Server_Database - Fatal编程技术网

使用union和具有视图的列的SQL Server查询

使用union和具有视图的列的SQL Server查询,sql,sql-server,database,Sql,Sql Server,Database,使用SQLServer数据库,我有一些SQL代码,它试图使用union从两个表中提取数据,并且工作正常 新的需求是向现有的SQL语句中添加一列,该语句从视图中读取数据。我运行了单独的SQL语句,它们在添加新列后运行良好,并且比原来的语句稍长 现在尝试将所有SQL语句与union一起运行,它将永远运行 select col 1, col 2, col3, case when 'ee' = (select col 5 from view1 where X.id =

使用SQLServer数据库,我有一些SQL代码,它试图使用union从两个表中提取数据,并且工作正常

新的需求是向现有的SQL语句中添加一列,该语句从视图中读取数据。我运行了单独的SQL语句,它们在添加新列后运行良好,并且比原来的语句稍长

现在尝试将所有SQL语句与union一起运行,它将永远运行

select 
    col 1, col 2, col3, 
    case 
       when 'ee' = (select col 5 from view1 where X.id = id) 
          then 'xx'  
          else 'yy' 
    end as newcol1
from
    X, Y, Z
where 
    condn 1 and condn 2

union

select 
    col 1, col 2, col3, 
    case 
       when 'ee' = (select col 5 from view1 where X.id = id) 
          then 'xx' 
          else 'yy' 
    end as newcol1 
from 
    X, Y, Z
where 
    condn 3 and condn 4

union

select 
    col 1, col 2, col3, 
    case 
       when 'ee' = (select col 5 from view1 where X.id = id) 
          then 'xx' 
          else 'yy' 
    end as newcol1 
from 
    X, Y, Z
where 
    condn 5 and condn 6

对优化此查询有何建议

很多人忽略的一件事是,UNION不仅返回子查询所有行的UNION,还将检查重复项,因此可能会大大降低查询速度。如果希望返回三个子查询的所有结果(包括重复项),则应使用UNION all,这通常要快得多

例如,假设您从各个子查询中获得以下结果:

Query 1   Query 2   Query 3
-------   -------   -------
1, 1, 1   1, 1, 1   4, 5, 6
2, 2, 2   3, 3, 3   7, 8, 9
1, 2, 3   3, 2, 1   1, 2, 3
3, 2, 1             3, 2, 1
使用UNION,您将获得:

1, 1, 1
2, 2, 2
1, 2, 3
3, 2, 1
3, 3, 3
4, 5, 6
7, 8, 9
1, 1, 1
2, 2, 2
1, 2, 3
3, 2, 1
1, 1, 1
3, 3, 3
3, 2, 1
4, 5, 6
7, 8, 9
1, 2, 3
3, 2, 1
使用UNION,您将获得:

1, 1, 1
2, 2, 2
1, 2, 3
3, 2, 1
3, 3, 3
4, 5, 6
7, 8, 9
1, 1, 1
2, 2, 2
1, 2, 3
3, 2, 1
1, 1, 1
3, 3, 3
3, 2, 1
4, 5, 6
7, 8, 9
1, 2, 3
3, 2, 1

如果您确实需要查询只返回三个子查询中不同的行,那么您可能需要在查询返回的列上添加索引,可能当前查询依赖于SQL Server创建的自动索引,而这些更改使优化器停止使用它们。

许多人忽略的一点是,UNION不仅返回子查询所有行的UNION,还将检查重复项,因此可能会大大降低查询速度。如果希望返回三个子查询的所有结果(包括重复项),则应使用UNION all,这通常要快得多

例如,假设您从各个子查询中获得以下结果:

Query 1   Query 2   Query 3
-------   -------   -------
1, 1, 1   1, 1, 1   4, 5, 6
2, 2, 2   3, 3, 3   7, 8, 9
1, 2, 3   3, 2, 1   1, 2, 3
3, 2, 1             3, 2, 1
使用UNION,您将获得:

1, 1, 1
2, 2, 2
1, 2, 3
3, 2, 1
3, 3, 3
4, 5, 6
7, 8, 9
1, 1, 1
2, 2, 2
1, 2, 3
3, 2, 1
1, 1, 1
3, 3, 3
3, 2, 1
4, 5, 6
7, 8, 9
1, 2, 3
3, 2, 1
使用UNION,您将获得:

1, 1, 1
2, 2, 2
1, 2, 3
3, 2, 1
3, 3, 3
4, 5, 6
7, 8, 9
1, 1, 1
2, 2, 2
1, 2, 3
3, 2, 1
1, 1, 1
3, 3, 3
3, 2, 1
4, 5, 6
7, 8, 9
1, 2, 3
3, 2, 1

如果确实需要查询只返回三个子查询中不同的行,则可能需要在查询返回的列上添加索引,可能当前查询依赖于SQL Server创建的自动索引,并且更改使优化器停止使用它们。

我建议重写整个查询:

SELECT col 1, col 2, col3, 
    case 
       when v.col5 = 'ee'
          then 'xx'  
          else 'yy' end as newcol1
FROM X
INNER JOIN Y ON Y.??? = X.???
INNER JOIN Z ON Z.??? = X.???
LEFT OUTER JOIN view1 v ON v.id = X.id AND col5 = 'ee' 
WHERE (condn 1 and condn 2)
   OR (condn 3 and condn 3)
   OR (condn 5 and condn 6)

这样,表X、Y、Z只需读取一次。

我建议重写整个查询:

SELECT col 1, col 2, col3, 
    case 
       when v.col5 = 'ee'
          then 'xx'  
          else 'yy' end as newcol1
FROM X
INNER JOIN Y ON Y.??? = X.???
INNER JOIN Z ON Z.??? = X.???
LEFT OUTER JOIN view1 v ON v.id = X.id AND col5 = 'ee' 
WHERE (condn 1 and condn 2)
   OR (condn 3 and condn 3)
   OR (condn 5 and condn 6)

这样,表X、Y、Z只需读取一次。

这不是查询。。。这是伪代码。。。从X,Y,Z是3路笛卡尔积的ANSII89语法。这本身就应该表现得很糟糕。最重要的是,相关子查询从view1中选择Col 5。。。将对外部查询中的每一行执行一次。。。然后。。。你做了三次。。。最重要的是,您使用的是联合,而不是所有联合,这意味着您在混合中添加了一个独特的操作。你可能会有一场完美的风暴25年前,在ANSI-92 SQL标准中,旧样式的逗号分隔表列表样式被正确的ANSI连接语法所取代,对于响应,不鼓励使用它。将从更改为使用联接。如何将newcol1更改为???为了表现得更好。使用上面的方法,我能够得到我所需要的结果,但是它的性能很差。请提供一个例子作为vladatr。这不是一个查询。。。这是伪代码。。。从X,Y,Z是3路笛卡尔积的ANSII89语法。这本身就应该表现得很糟糕。最重要的是,相关子查询从view1中选择Col 5。。。将对外部查询中的每一行执行一次。。。然后。。。你做了三次。。。最重要的是,您使用的是联合,而不是所有联合,这意味着您在混合中添加了一个独特的操作。你可能会有一场完美的风暴25年前,在ANSI-92 SQL标准中,旧样式的逗号分隔表列表样式被正确的ANSI连接语法所取代,对于响应,不鼓励使用它。将从更改为使用联接。如何将newcol1更改为???为了表现得更好。使用上面的方法,我能够得到我所需要的结果,但是它的性能很差。请以vladatr为例。