Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.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 - Fatal编程技术网

Sql 完全外部联接行为异常

Sql 完全外部联接行为异常,sql,sql-server,Sql,Sql Server,我在同一个sql server数据库中有两个表,它们存储连续两个季度的应用程序名和用户名(以及其他内容)。我想要的是一个完整连接,它显示表a中不在表B中的用户,反之亦然 编辑:表a和表b都包含两个或多个记录,其中AppName和Username的值相同,因此需要使用不同的名称。我编辑了下面的示例以反映这一点 表a: ----------------------- | AppName | Username | ----------------------- | app1 | jdoe

我在同一个sql server数据库中有两个表,它们存储连续两个季度的应用程序名和用户名(以及其他内容)。我想要的是一个完整连接,它显示表a中不在表B中的用户,反之亦然

编辑:表a和表b都包含两个或多个记录,其中AppName和Username的值相同,因此需要使用不同的名称。我编辑了下面的示例以反映这一点

表a:

-----------------------
| AppName  | Username |
-----------------------
| app1     | jdoe     |
| app1     | jsmith   |
| app1     | jdoe     |
| app2     | jsmith   |
-----------------------
表b:

-----------------------
| AppName  | Username |
-----------------------
| app1     | fbar     |
| app1     | jsmith   |
| app1     | jboehner |
| app1     | fbar     |
| app3     | jboehner |
-----------------------
SQL:

预期结果:

-----------------------
| q2       | q3       |
-----------------------
| jdoe     |          |
| jsmith   | jsmith   |
|          | fbar     |
-----------------------
|          | jboehner |
-----------------------
实际结果:

-----------------------
| q2       | q3       |
-----------------------
| jsmith   | jsmith   |
-----------------------

什么使???

在外部联接表(在本例中是两个表)上使用WHERE子句将其更改为内部联接,因为过滤器应用于联接的结果,并且必须满足所有条件。在您的情况下,这是不可能的,除非是在匹配的行上(它强制它进行内部联接)。我猜这就是你的意思:

SELECT DISTINCT a.username as q2, b.username as q3
FROM dbo.tablea as a
FULL OUTER JOIN dbo.tableb as b
ON a.username = b.username
AND (a.appname = b.appname)
WHERE a.appname = 'app1' OR b.appname = 'app1';

-- or

SELECT DISTINCT a.username as q2, b.username as q3
FROM dbo.tablea as a
FULL OUTER JOIN dbo.tableb as b
ON a.username = b.username
AND (a.appname = b.appname)
WHERE 'app1' IN (a.appname, b.appname);

对外部联接表(在本例中是两个表)使用WHERE子句会将其更改为内部联接,因为过滤器应用于联接的结果,并且必须满足所有条件。在您的情况下,这是不可能的,除非是在匹配的行上(它强制它进行内部联接)。我猜这就是你的意思:

SELECT DISTINCT a.username as q2, b.username as q3
FROM dbo.tablea as a
FULL OUTER JOIN dbo.tableb as b
ON a.username = b.username
AND (a.appname = b.appname)
WHERE a.appname = 'app1' OR b.appname = 'app1';

-- or

SELECT DISTINCT a.username as q2, b.username as q3
FROM dbo.tablea as a
FULL OUTER JOIN dbo.tableb as b
ON a.username = b.username
AND (a.appname = b.appname)
WHERE 'app1' IN (a.appname, b.appname);

应该在哪里,或者不在哪里,以及:
其中a.appname='app1'或b.appname='app1'

WHERE应该是或不是,并且:
SELECT  DISTINCT a.username as q2, b.username as q3
FROM    (SELECT x.* FROM tablea x WHERE x.appname = 'app1') as a
FULL JOIN (SELECT y.* FROM tableb y WHERE y.appname = 'app1') as b 
ON a.username = b.username
其中a.appname='app1'或b.appname='app1'

SELECT  DISTINCT a.username as q2, b.username as q3
FROM    (SELECT x.* FROM tablea x WHERE x.appname = 'app1') as a
FULL JOIN (SELECT y.* FROM tableb y WHERE y.appname = 'app1') as b 
ON a.username = b.username
编辑#1:

编辑#2:

编辑#3:

编辑#1:

编辑#2:

编辑#3:



既然您已经在适当的位置创建了带有空值的数据集,您就不能对a.username=b.username和a.appname=b.appname进行完整的外部联接,然后将WHERE条件放在事实之后吗?SQL Server是否能够以这种方式将筛选器推送到各个表中?我习惯于手动将筛选器下推到派生表中。@Love2Learn yes,但重要的是WHERE子句不能对两个表都有AND(这使它成为一个内部联接)。在完全联接的情况下,两个表上都有WHERE子句不会导致内部联接或左外部联接吗?只需将where条件添加到on子句。@Andrew如果只将where子句移动到on,对于除app1之外的其他应用程序,您还将获得不匹配的行-筛选器不适用。由于您已经在适当的位置创建了带有null的数据集,您不能对a.username=b.username和a.appname=b.appname进行完整的外部联接,然后将WHERE条件放在事实之后吗?SQL Server能否推送是否以这种方式过滤到各个表中?我习惯于手动将筛选器下推到派生表中。@Love2Learn yes,但重要的是WHERE子句不能对两个表都有AND(这使它成为一个内部联接)。在完全联接的情况下,两个表上都有WHERE子句不会导致内部联接或左外部联接吗?只需将where条件添加到on子句。@Andrew如果您只将where子句移动到on,您还将获得除app1以外的其他应用程序的不匹配行-筛选器不适用。否,这将允许任一表在
appname“app1”中引入行。
。否,这将允许任何一个表在
appname'app1'
@AaronBertrand的位置引入行,如果该表在appname上建立索引,这可能会产生非常有效的计划。如果索引正确,甚至可能导致合并联接而不进行排序。事实上,如果过滤器向外移动,我看不出查询如何变得更快。我很感兴趣。考虑使用巴斯宾.@ AaronBertrand(AppNead,用户名)的索引包括(*)?如果appname上的筛选器具有高度选择性,并且表很大,则include应该是可选的。@AaronBertrand如果表在appname上建立索引,这可能会产生非常有效的计划。如果索引正确,甚至可能导致合并联接而不进行排序。事实上,如果过滤器向外移动,我看不出查询如何变得更快。我很感兴趣。考虑使用巴斯宾.@ AaronBertrand(AppNead,用户名)的索引包括(*)?如果appname上的筛选器具有高度选择性且表很大,则include应该是可选的。
Test #1 
{
Table 'ProductModel'. Scan count 0, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Product'. Scan count 0, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
}
Test #2 
{
Table 'ProductModel'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Product'. Scan count 1, logical reads 15, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
}