0

我在同一个 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   |
-----------------------

是什么赋予了??

4

3 回答 3

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);
于 2013-10-09T18:13:37.400 回答
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:

在此处输入图像描述

于 2013-10-09T18:33:48.770 回答
-3

where 应该是或不是: WHERE a.appname = 'app1' OR b.appname = 'app1'

于 2013-10-09T18:30:03.580 回答