3

私はこの問題への答えを求めてStackOverflowとGoogleを精査しました。

Microsot SQLServer2008ビューを作成しようとしています。ストアドプロシージャではありません。関数ではありません。単なるクエリ(つまりビュー)。

私は3つのテーブルを持っています。最初のテーブルは、「CompanyID」などの共通キーを定義します。他の2つのテーブルには、「EmployeeName」などの一般的なフィールドがあります。

WHERE句に「WHERECompanyID=12」と表示されている場合、次のような単一のテーブル結果が必要です。

CompanyID | TableA    | TableB
12        | John Doe  | John Doe
12        | Betty Sue | NULL
12        | NULL      | Billy Bob

私は次のような完全な外部結合を試しました:

SELECT Company.CompanyID,
    TableA.EmployeeName,
    TableB.EmployeeName
FROM Company
FULL OUTER JOIN TableA ON Company.CompanyID = TableA.CompanyID
FULL OUTER JOIN TableB ON 
    Company.CompanyID = TableB.CompanyID AND 
    (TableA.EmployeeName IS NULL OR TableB.EmployeeName IS NULL OR TableB.EmployeeName = TableA.EmployeeName)

一致した1つのテーブルからのみNULLを取得していますが、他のテーブルの展開は取得していません。上記のサンプルでは、​​基本的に1行目と3行目のみを取得しており、2行目は取得していません。

誰かが私がこのクエリを作成するのを手伝って、これがどのように正しく行われるかを教えてもらえますか?

ところで、私はすでに非常にきれいに見え、メモリ内のテーブルにデータを入力するストアドプロシージャを持っていますが、それは私が望んでいることではありません。

ありがとう。

- 編集:

これは、現在機能していないものの完全なサンプルです(「誰か2」と「誰か3」が欠落しています。

DECLARE @Company TABLE
(
    CompanyID int
)

INSERT INTO @Company (CompanyID) VALUES (10)
INSERT INTO @Company (CompanyID) VALUES (12)

DECLARE @TableA TABLE
(
    EmployeeId int,
    CompanyId int,
    EmployeeName varchar(30)
)

DECLARE @TableB TABLE
(
    EmployeeId int,
    CompanyId int,
    EmployeeName varchar(30)
)

INSERT INTO @TableA ( EmployeeId, CompanyId, EmployeeName )
VALUES ( 1, 10, 'someone' )

--INSERT INTO @TableA ( EmployeeId, CompanyId, EmployeeName )
--VALUES ( 2, 12, 'someone 2' )

INSERT INTO @TableA ( EmployeeId, CompanyId, EmployeeName )
VALUES ( 3, 12, 'someone 3' )

INSERT INTO @TableA ( EmployeeId, CompanyId, EmployeeName )
VALUES ( 3, 12, 'someone 4' )

INSERT INTO @TableB ( EmployeeId, CompanyId, EmployeeName )
VALUES ( 1, 10, 'someone' )

INSERT INTO @TableB ( EmployeeId, CompanyId, EmployeeName )
VALUES ( 2, 12, 'someone 2' )

--INSERT INTO @TableB ( EmployeeId, CompanyId, EmployeeName )
--VALUES ( 3, 12, 'someone 3' )

INSERT INTO @TableB ( EmployeeId, CompanyId, EmployeeName )
VALUES ( 3, 12, 'someone 4' )

SELECT Company.CompanyID,
    TableA.EmployeeName,
    TableB.EmployeeName
FROM @Company Company
FULL OUTER JOIN @TableA TableA ON Company.CompanyID = TableA.CompanyID
FULL OUTER JOIN @TableB TableB ON Company.CompanyID = TableB.CompanyID
WHERE
(
    TableA.EmployeeName IS NULL OR TableB.EmployeeName IS NULL OR 
    TableB.EmployeeName = TableA.EmployeeName
)
AND Company.CompanyID = 12

結果:

CompanyID   EmployeeName    EmployeeName
12          someone 4       someone 4

私が欲しいもの:

CompanyID   EmployeeName    EmployeeName
12          NULL            someone 2
12          someone 3       NULL
12          someone 4       someone 4
4

4 に答える 4

2

これを試して:

SELECT Company.CompanyID,
    TableA.EmployeeName,
    TableB.EmployeeName
FROM Company
LEFT OUTER JOIN TableA ON Company.CompanyID = TableA.CompanyID
LEFT OUTER JOIN TableB ON Company.CompanyID = TableB.CompanyID
WHERE (TableA.EmployeeName IS NULL OR TableB.EmployeeName IS NULL OR TableB.EmployeeName = TableA.EmployeeName)

OPがテストデータと期待される結果セットを提供した後の編集

これを試してください(質問の表とテストデータ):

DECLARE @Company TABLE (CompanyID int)
DECLARE @TableA TABLE (EmployeeId int,CompanyId int,EmployeeName varchar(30))
DECLARE @TableB TABLE (EmployeeId int,CompanyId int,EmployeeName varchar(30))

set nocount on
INSERT INTO @Company (CompanyID) VALUES (10)
INSERT INTO @Company (CompanyID) VALUES (12)

--INSERT INTO @TableA ( EmployeeId, CompanyId, EmployeeName )--VALUES ( 2, 12, 'someone 2' )
INSERT INTO @TableA ( EmployeeId, CompanyId, EmployeeName )VALUES ( 1, 10, 'someone' )
INSERT INTO @TableA ( EmployeeId, CompanyId, EmployeeName )VALUES ( 3, 12, 'someone 3' )
INSERT INTO @TableA ( EmployeeId, CompanyId, EmployeeName )VALUES ( 3, 12, 'someone 4' )

--INSERT INTO @TableB ( EmployeeId, CompanyId, EmployeeName )--VALUES ( 3, 12, 'someone 3' )
INSERT INTO @TableB ( EmployeeId, CompanyId, EmployeeName )VALUES ( 1, 10, 'someone' )
INSERT INTO @TableB ( EmployeeId, CompanyId, EmployeeName )VALUES ( 2, 12, 'someone 2' )
INSERT INTO @TableB ( EmployeeId, CompanyId, EmployeeName )VALUES ( 3, 12, 'someone 4' )
set nocount off

SELECT coalesce(TableA.CompanyID,TableB.CompanyID) CompanyID,
    TableA.EmployeeName,
    TableB.EmployeeName
FROM @TableA TableA
FULL OUTER jOIN  @TableB TableB ON TableA.CompanyID = TableB.CompanyID AND TableB.EmployeeName = TableA.EmployeeName
WHERE coalesce(TableA.CompanyID,TableB.CompanyID) = 12

出力:

CompanyID   EmployeeName                   EmployeeName
----------- ------------------------------ ------------------------------
12          NULL                           someone 2
12          someone 3                      NULL
12          someone 4                      someone 4

(3 row(s) affected)
于 2010-03-25T17:51:20.120 に答える
1

これを試して

DECLARE @Company TABLE 
( 
    CompanyID int 
) 

INSERT INTO @Company (CompanyID) VALUES (10) 
INSERT INTO @Company (CompanyID) VALUES (12) 

DECLARE @TableA TABLE 
( 
    EmployeeId int, 
    CompanyId int, 
    EmployeeName varchar(30) 
) 

DECLARE @TableB TABLE 
( 
    EmployeeId int, 
    CompanyId int, 
    EmployeeName varchar(30) 
) 

INSERT INTO @TableA ( EmployeeId, CompanyId, EmployeeName ) 
VALUES ( 1, 10, 'someone' ) 

--INSERT INTO @TableA ( EmployeeId, CompanyId, EmployeeName ) 
--VALUES ( 2, 12, 'someone 2' ) 

INSERT INTO @TableA ( EmployeeId, CompanyId, EmployeeName ) 
VALUES ( 3, 12, 'someone 3' ) 

INSERT INTO @TableA ( EmployeeId, CompanyId, EmployeeName ) 
VALUES ( 3, 12, 'someone 4' ) 

INSERT INTO @TableB ( EmployeeId, CompanyId, EmployeeName ) 
VALUES ( 1, 10, 'someone' ) 

INSERT INTO @TableB ( EmployeeId, CompanyId, EmployeeName ) 
VALUES ( 2, 12, 'someone 2' ) 

--INSERT INTO @TableB ( EmployeeId, CompanyId, EmployeeName ) 
--VALUES ( 3, 12, 'someone 3' ) 

INSERT INTO @TableB ( EmployeeId, CompanyId, EmployeeName ) 
VALUES ( 3, 12, 'someone 4' ) 

INSERT INTO @TableB ( EmployeeId, CompanyId, EmployeeName )  
VALUES ( 3, 12, 'someone 4' )  

SELECT Company.CompanyID,  
   A.EmployeeNameTableA,  
   A.EmployeeNameTAbleB 
FROM @Company Company  
left OUTER JOIN (select TableA.EmployeeName as EmployeeNameTableA, TableB.EmployeeName as EmployeeNameTableB , 
coalesce(TableA.CompanyID,TableB.CompanyID) as CompanyID 
from @TableA TableA  
FULL OUTER JOIN @TableB TableB ON TableA.CompanyID = TableB.CompanyID and TableB.EmployeeName = TableA.EmployeeName and (tablea.companyid = 12 or tableb.companyid = 12))A ON Company.CompanyID = A.CompanyID  

WHERE Company.CompanyID = 12  
于 2010-03-25T18:56:48.370 に答える
1

FULL OUTER JOINは、companyIDとemployeeNameのTableAとTableBの間でのみ行う必要があります。これは、1つのテーブルにのみ存在する場合にNULLとして入力する値であるためです。
これを取得したら、Companyと内部結合して、Companyから他のデータを取得できます。

フルアウタージョインソリューション:

select Company.companyID, EmployeeNameA, EmployeeNameB
from (
    SELECT isnull(TableA.CompanyID, TableB.CompanyID) as companyID,
        TableA.EmployeeName as EmployeeNameA,
        TableB.EmployeeName as EmployeeNameB
    FROM @TableA TableA 
    FULL OUTER JOIN @TableB TableB ON TableA.EmployeeName = TableB.EmployeeName and TableA.companyID = TableB.companyID
    WHERE
     TableA.CompanyID = 12 or TableB.CompanyID = 12 
) merged
inner join @Company Company
    on merged.companyID = Company.companyID

個人的には、FULLOUTERJOINSの観点から考えるのは難しいと思います。これに対する私のアプローチは次のとおりです。影響を受けるテーブル間でUNIONを作成し、左結合を使用して両方のテーブルからデータを取得し、必要なときにNULLを取得することで、結果に必要な個別のEmployeeNameを見つけます。

LEFT JOINの例:

select c.companyID, a.employeeName, b.employeeName
from  (
    select distinct employeeName, companyID
    from  (
        select a.employeeName, companyID 
        from @tableA  a
        union 
        select b.employeeName, companyID
        from @tableB b
    ) a
) z
inner join @company c
    on c.companyID = z.companyID
left join @tableA  a
    on z.companyID = a.companyID and z.employeeName = a.employeeName
left join @tableB  b
    on z.companyID = b.companyID and z.employeeName = b.employeeName
where z.companyID = 12
于 2010-03-25T19:17:14.863 に答える
0

これは、ディミトリス・バルタスの答えのバリエーションであり、私が考えていたものに近いものです。

SELECT Company.CompanyID,
    TableA.EmployeeName as EmployeeNameTableA,
    TableB.EmployeeName as EmployeeNameTableB
FROM @TableA TableA 
FULL OUTER JOIN @TableB TableB ON TableA.EmployeeName = TableB.EmployeeName 
    and TableA.companyID = TableB.companyID
INNER JOIN @Company Company ON (
    Company.CompanyID = TableA.CompanyId OR Company.CompanyID = TableB.CompanyId
)
WHERE Company.CompanyID = 12

私が探している重要なこと(そしてこのサンプルはこれを行いませんが、Dimitrisの可能性があります)は、実行プランがフィルターで除外される前に、結合された各テーブルのすべての行をふるいにかけないように、CompanyIDで事前フィルター処理することでしたCompanyID。私の場合、2つの結合されたテーブルは非常に低速です。

私が最終的にしなければならないことは、sprocsを使い続けることだと思います。

于 2010-03-25T21:19:25.600 に答える