2

FULL OUTER JOIN3つのテーブルで、共通の行をマージして実行したいと思います。

SELECT * FROM Users

id  Username  Fullname
==  ========  =====================
 7  iboyd     Ian Boyd
 8  nicholle  Nicholle Kuzniak
10  jamie     Jamie Bellaire

3 row(s) affected


SELECT * FROM GrobUsers

id  Username  Fullname
==  ========  =====================
 7  iboyd     Ian Alexander Boyd 
 8  nicholle  Nicholle Bachand
 9  chris     Chris Windibank

3 row(s) affected


SELECT * FROM FrobUsers

id  Username  Fullname
==  ========  =====================
 7  ian       Ian
 9  chris     Chris W.
10  jamie     James Bellaire

3 row(s) affected

id列に基づいてテーブルをマージしたい。

これにより、他の列の値が異なる場合に競合をどのように解決するかという問題が発生します。UsernamesとFullNameの間の競合を解決するために適用できるアルゴリズムは次のとおりです。

 if (id's are equal) then 
    pick one; i don't care

私は次の線に沿って何かを試しました:

SELECT
   COALESCE(Users.id, GrobUsers.id, FrobUsers.id) AS id,
   COALESCE(Users.Username, GrobUsers.Username, FrobUsers.Username) AS Username,
   COALESCE(Users.FullName, GrobUsers.FullName, FrobUsers.FullName) AS Fullname
FROM Users
   FULL OUTER JOIN GrobUsers ON GrobUsers.id = Users.id

   FULL OUTER JOIN FrobUsers ON FrobUsers.id = .....something......
4

2 に答える 2

3

典型的なトリック-意味のない集計関数を使用します。

select id, min(username), min(fullname) from (
  SELECT * FROM Users 
  union
  SELECT * FROM FrobUsers
  union
  SELECT * FROM GrobUsers  
) as foo
group by foo.id

うーん...しかし、あるテーブルからユーザー名を選択し、別のテーブルからフルネームを選択する場合があります。それでも気にしない場合は、それを使用してください。そうでない場合は...多分

select id, username, fullname from (
  select id, username, fullname, takeme = row_number() over (partition by id)
  from (
    SELECT * FROM Users 
    union
    SELECT * FROM FrobUsers
    union
    SELECT * FROM GrobUsers  
  ) as foo
) as bar
where bar.takeme = 1
于 2011-06-10T21:28:52.133 に答える
1

あなたが与えている例では、結合はまったく必要ありません。これが実際の例であり、不自然な例ではないことを願っています。ここでやりたいことは非常に単純です。結合はまったく必要なく、row_numberも必要ありません。あなたはこのようにそれを行うことができます:

select id,Username,Fullname from Users
UNION ALL
select id,Username,Fullname from GrobUsers 
where id not in (select id from Users)
UNION ALL
select id,Username,Fullname from FrobUsers  
where id not in (select id from Users) and id not in (select id from GrobUsers)

そしてそれはあなたにこれを与えるでしょう:

id          Username   Fullname        
----------- ---------- -----------------
7           iboyd      Ian Boyd         
8           nicholle   Nicholle Kuzniak 
9           chris      Chris Windibank  
10          jamie      Jamie Bellaire   

(4 row(s) affected)

これが私が使用したテストケースです:

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Users]') AND type in (N'U'))
DROP TABLE [dbo].[Users]
GO

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[GrobUsers]') AND type in (N'U'))
DROP TABLE [dbo].[GrobUsers]
GO

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[FrobUsers]') AND type in (N'U'))
DROP TABLE [dbo].[FrobUsers]
GO

CREATE TABLE [dbo].[Users](
    [Id] [int] NOT NULL,
    [Username] [nchar](50) NULL,
    [Fullname] [nchar](50) NULL,
 CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

CREATE TABLE [dbo].[GrobUsers](
    [Id] [int] NOT NULL,
    [Username] [nchar](50) NULL,
    [Fullname] [nchar](50) NULL,
 CONSTRAINT [PK_GrobUsers] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

CREATE TABLE [dbo].[FrobUsers](
    [Id] [int] NOT NULL,
    [Username] [nchar](50) NULL,
    [Fullname] [nchar](50) NULL,
 CONSTRAINT [PK_FrobUsers] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

INSERT INTO Users Values (7,'iboyd','Ian Boyd' )
INSERT INTO Users Values (8,'nicholle','Nicholle Kuzniak' )
INSERT INTO Users Values (10,'jamie','Jamie Bellaire' )


INSERT INTO [GrobUsers] Values (7,'iboyd','Ian Alexander Boyd ' )
INSERT INTO [GrobUsers] Values (8,'nicholle','Nicholle Bachand' )
INSERT INTO [GrobUsers] Values (9,'chris','Chris Windibank' )

INSERT INTO [FrobUsers] Values (7,'iboyd','Ian' )
INSERT INTO [FrobUsers] Values (9,'nicholle','Chris W.' )
INSERT INTO [FrobUsers] Values (10,'jamie','James Bellaire' )
GO
于 2011-06-10T22:15:41.150 に答える