SQL - 按名称加入2个不同的表而不重复

时间:2016-09-15 22:52:40

标签: sql sql-server join duplicates

我在查看2个不同的表时遇到问题:A和B.每个表都代表一个班级的得分结果。表A和表B代表不同的测试。有些学生参加了两项考试,有些学生只考了一次。

以下是我正在使用的简短版本:

CREATE TABLE A
(
fn varchar(50),
ln varchar(50),
score1 int
);

CREATE TABLE B
(
fn varchar(50),
ln varchar(50),
score2 int
);

INSERT INTO A (fn, ln, score)
VALUES ('abe','farm',90);
INSERT INTO A (fn, ln, score)
VALUES ('carly','lina',70);
INSERT INTO A (fn, ln, score)
VALUES ('bobby','echo',40);
INSERT INTO A (fn, ln, score)
VALUES ('joe','robin',11);

INSERT INTO B (fn, ln, score)
VALUES ('abe','farm',95);
INSERT INTO B (fn, ln, score)
VALUES ('carly','lina',75);
INSERT INTO B (fn, ln, score)
VALUES ('geb','lina',100);
INSERT INTO B (fn, ln, score)
VALUES ('bobby','echo',40);

我希望得到一个结果数据表,代表每个学生(没有重复),使不存在的分数为NULL,并相应地为每个学生匹配名字和姓氏:

/===========================================\
| fn       | ln       | score1   | score2   |
|===========================================|
| abe      | farm     | 90       | 95       |
| bobby    | echo     | 40       | 40       |
| carly    | lina     | 70       | 75       |
| geb      | lina     | NULL     | 100      |
| joe      | robin    | 11       | NULL     |
\===========================================/

我在Microsoft SQL Server中工作。

5 个答案:

答案 0 :(得分:2)

SELECT
    t.fn
    ,t.ln
    ,MAX(t.score1) as score1
    ,MAX(t.score2) as score2
FROM
    (
       SELECT fn, ln, score as score1, NULL as score2
       FROM
          A
       UNION ALL
       SELECT fn, ln, NULL, score2
       FROM
          B
    ) t
GROUP BY
    t.fn, t.ln

答案 1 :(得分:0)

select FName
      ,LName
      ,Score1 = sum(Score1)
      ,Score2 = sum(Score2)
from
(
select 
    FName = A.Fn
   ,LName = A.Ln 
   ,Score1 = A.Score1
   ,Score2 = 0 
from #A A
union all 
select 
    FName = B.Fn
   ,LName = B.Ln 
   ,Score1 = 0
   ,Score2 = B.Score2 
from #B B
) x
Group by Fname, LName 

答案 2 :(得分:0)

您可以尝试这样的查询:要获得结果集完全加入无效

SELECT
  a.fn,
  a.ln,
  a.score1,
  b.score2
FROM a
LEFT JOIN b
  ON a.fn = b.fn
  AND a.ln = b.ln
UNION
SELECT
  b.fn,
  b.ln,
  a.score1,
  b.score2
FROM b
LEFT JOIN a
  ON a.fn = b.fn
  AND a.ln = b.ln
WHERE a.fn IS NULL
AND a.ln IS NULL

答案 3 :(得分:0)

您可以使用UNION ALL或FULL OUTER JOIN。

    ;WITH cte_1
     As (       SELECT fn, ln, score as score1, NULL as score2
   FROM  A
   UNION ALL
   SELECT fn, ln, NULL, score as score2
   FROM B)
     SELECT fn,ln,Max(score1) score1,Max(score2) score2
    FROM cte_1
    GROUP BY fn,ln

或者

    SELECT ISNULL(a.fn, b.fn) fn, 
                   ISNULL(a.ln, b.ln) ln, 
                     a.score score1, b.score score2 
     FROM A
        FULL JOIN B ON A.fn = B.fn and A.ln = B.ln

答案 4 :(得分:0)

试试这个

SELECT COALESCE(a.fn, b.fn) fn, 
   COALESCE(a.ln, b.ln) ln, 
   a.score score1, b.score score2  
FROM a FULL JOIN b ON b.fn = a.fn AND b.ln = a.ln 
ORDER BY fn