我在同一个sql-server数据库中有两个表,它们连续两个季度存储应用程序名称和用户名(以及其他内容)。我想要的是一个完整的连接,它向表A中的用户显示不在表B中,反之亦然。
编辑: table_a和table_b都包含两个或多个记录,其中AppName和Username具有相同的值,因此需要DISTINCT。我编辑了下面的例子来反映这一点。
表-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:
SELECT DISTINCT a.username as q2, b.username as q3
FROM tablea as a
FULL JOIN tableb as b
ON a.username = b.username
WHERE a.appname = 'app1'
AND b.appname = 'app1'
预期结果:
-----------------------
| q2 | q3 |
-----------------------
| jdoe | |
| jsmith | jsmith |
| | fbar |
-----------------------
| | jboehner |
-----------------------
实际结果:
-----------------------
| q2 | q3 |
-----------------------
| jsmith | jsmith |
-----------------------
是什么?
答案 0 :(得分:4)
在OUTER JOINed表上使用WHERE子句(在这种情况下,两个表)都将其更改为INNER JOIN,因为过滤器应用于连接的结果,所有条件必须是满足。在您的情况下,除了匹配的行(它强制它为INNER JOIN)之外,这是不可能的。我怀疑这就是你的意思:
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);
答案 1 :(得分:3)
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:
USE AdventureWorks2008R2;
SET STATISTICS IO ON;
SET NOCOUNT ON;
PRINT 'Test #1 '
PRINT '{'
SELECT DISTINCT x.Name, y.Name
FROM
(
SELECT p.*
FROM Production.Product p
WHERE p.Name = 'HL Road Frame'
) x
FULL OUTER JOIN
(
SELECT pm.*
FROM Production.ProductModel pm
WHERE pm.Name = 'HL Road Frame'
) y ON x.ProductModelID = y.ProductModelID
PRINT '}'
GO
PRINT 'Test #2 '
PRINT '{'
SELECT DISTINCT p.Name, pm.Name
FROM Production.Product p
FULL OUTER JOIN Production.ProductModel pm
ON p.ProductModelID = pm.ProductModelID
AND (p.Name = pm.Name)
WHERE p.Name = 'HL Road Frame' OR pm.Name = 'HL Road Frame'
PRINT '}'
GO
SET STATISTICS IO OFF;
编辑#2:
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.
}
编辑#3:
答案 2 :(得分:-3)
应该在哪里,或者不是: WHERE a.appname ='app1'或b.appname ='app1'