SQL:避免重复数据

时间:2013-05-19 11:36:19

标签: sql-server sql-server-2008

表1:

Person_ID   Name    Salary_Revisions
1           Test1   100
1           Test1   200
2           Test2   300
2           Test2   400

表2:

Person ID                  Department
-------------------------- ---------------- 
1                          Physics
1                          Chemistry
2                          Maths

我想得到如下结果:

Person_ID             Name               Salary_Revisions       Department
--------------------- ------------------ ---------------------- --------------
1                     Test1              100                    Physics
1                     Test1              200                    Chemistry
2                     Test2              300                    Maths
2                     Test2              400

实际值:

Person ID          Name      Salary Revisions      Department
------------------ --------- --------------------- ----------------
1                  Test1     100                   Physics
1                  Test1     200                   Physics
1                  Test1     100                   Chemistry
1                  Test1     200                   Chemistry
2                  Test2     300                   Maths
2                  Test2     400                   Maths

你能帮我实现预期的结果吗?

在实现这个的过程中,我通过使用person id将表1与表2联系起来,编写了一个存储过程。通过在Database中执行查询它返回实际结果。

SQL查询:

SELECT table1.person_ID, table1.name, table1.salary_revisions, table2.department 
from table1 
left outer join table2 on table1.person_id=table2.person_id

3 个答案:

答案 0 :(得分:1)

鉴于您的评论认为Revisions与Department之间没有关系,那么使用列表是有意义的。逗号分隔看起来不错。像这样:

 PERSON_ID  NAME   SALARY REVISION LIST  DEPARTMENT LIST
 ---------- ------ --------------------- ------------------------
 1          Test1  100, 200              Physics, Chemistry
 2          Test2  300, 400              Maths

以下是查询:

SELECT DISTINCT
       Person_ID,
       Name,
       STUFF((SELECT ', ' + CAST(S.Salary_Revisions AS VARCHAR(50))
              FROM Table1 S
              WHERE S.Person_ID = P.Person_ID
              FOR XML PATH ('')),1,2,'') AS [Salary Revision List],
       STUFF((SELECT ', ' + D.Department
              FROM Table2 D
              WHERE D.Person_ID = P.Person_ID
              FOR XML PATH ('')),1,2,'') AS [Department List]
FROM Table1 P

这是小提琴: http://sqlfiddle.com/#!3/27c07/3/0


原始答案

这很容易做到,但有一部分业务规则没有意义。为什么这一行没有部门?

Person_ID             Name               Salary_Revisions       Department
--------------------- ------------------ ---------------------- --------------
2                     Test2              400

表2中没有任何内容暗示2处的用户3002处的用户400之间存在差异。

您系统中的哪些数据暗示您显示的结果是正确的 - 结果也不会是:

Person_ID             Name               Salary_Revisions       Department
--------------------- ------------------ ---------------------- --------------
1                     Test1              100                    Physics
1                     Test1              200                    Chemistry
2                     Test2              300                    
2                     Test2              400                    Maths

Person_ID             Name               Salary_Revisions       Department
--------------------- ------------------ ---------------------- --------------
1                     Test1              100                    Physics
1                     Test1              200                    Chemistry
2                     Test2              300                    Maths
2                     Test2              400                    Maths

如果您没有逻辑上选择正确的数据,则无法执行此查询。

可能行的顺序很重要(这对SQL来说非常奇怪)。也许有些数据没有放入你需要的数据模型中?

答案 1 :(得分:1)

我不太了解使用场景,但我认为这就是你想要的。

两个CTE用于获取每个人每列的所有唯一值,并使用FULL OUTER JOIN逐行组合它们。

WITH salary_revision AS (
  SELECT person_id, name, salary_revisions sr, 
  ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY person_id) row
  FROM table1
), department AS (
  SELECT person_id, department,
  ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY person_id) row
  FROM table2
)
SELECT sr.person_id,sr.name, sr.sr, d.department
FROM salary_revision sr
FULL OUTER JOIN department d
  ON sr.person_id = d.person_id
 AND sr.row = d.row

An SQLfiddle to test with

答案 2 :(得分:-1)

    WITH salary_revision AS (
     SELECT person_id, name, salary_revisions sr, 
     ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY person_id) row
     FROM table1
    ), department AS (
     SELECT person_id, department,
     ROW_NUMBER() OVER (PARTITION BY person_id ORDER BY person_id) row
    FROM table2
    )

SELECT COALESCE(sr.person_id,d.person_id),sr.name,sr.sr,d.department    来自salary_revision sr    FULL OUTER JOIN部门d   ON sr.person_id = d.person_id   AND sr.row = d.row

给COALESCE它考虑第一个非空值。所以我们在每一行都得到了peson_id。