如何从视图中删除"重复"行?

Fet*_*Fet 4 sql t-sql sql-server-2005

当我加入主表时,我有一个工作正常的视图:

LEFT OUTER JOIN OFFICE ON CLIENT.CASE_OFFICE = OFFICE.TABLE_CODE.
Run Code Online (Sandbox Code Playgroud)

但是我需要添加以下连接:

LEFT OUTER JOIN OFFICE_MIS ON CLIENT.REFERRAL_OFFICE = OFFICE_MIS.TABLE_CODE 
Run Code Online (Sandbox Code Playgroud)

虽然我补充说DISTINCT,我仍然得到一个"重复"的行.我说"重复",因为第二行有不同的值.

但是,如果我将其更改为a LEFT OUTER,则会INNER JOIN丢失具有这些"重复"行的客户端的所有行.

我究竟做错了什么?如何从我的视图中删除这些"重复"行?


注意:

此问题不适用于此实例:

如何删除重复的行?

Jay*_*y S 8

如果行包含任何不同的列,DISTINCT将无法帮助您.显然,您要加入的其中一个表在另一个表中的单行中有多行.要获得一行,您必须消除要加入的表中的其他多行.

最简单的方法是增强where子句或JOIN限制,以便只加入你想要的单个记录.通常,这需要确定一个规则,该规则将始终从另一个表中选择"正确"条目.

我们假设您有一个简单的问题,例如:

Person:  Jane
Pets: Cat, Dog
Run Code Online (Sandbox Code Playgroud)

如果您在此处创建一个简单的联接,您将收到Jane的两条记录:

Jane|Cat
Jane|Dog
Run Code Online (Sandbox Code Playgroud)

如果您的观点是列出人和宠物的所有组合,这是完全正确的.但是,如果您的观点应该列出有宠物的人,或者列出人并展示他们的宠物之一,那么您就会遇到现在的问题.为此,您需要一个规则.

SELECT Person.Name, Pets.Name
FROM Person
  LEFT JOIN Pets pets1 ON pets1.PersonID = Person.ID
WHERE 0 = (SELECT COUNT(pets2.ID) 
             FROM Pets pets2
             WHERE pets2.PersonID = pets1.PersonID
                AND pets2.ID < pets1.ID);
Run Code Online (Sandbox Code Playgroud)

这样做是应用一个规则来限制连接中的Pets记录到具有最低ID的宠物(在Pets表中的第一个).WHERE子句基本上表示"没有宠物属于具有较低ID值的同一个人".

这将产生一个记录结果:

Jane|Cat
Run Code Online (Sandbox Code Playgroud)

您需要应用于视图的规则取决于您拥有的列中的数据,以及应在列中显示哪些"多个"记录.但是,这最终会隐藏一些数据,这可能不是您想要的.例如,上述规则隐藏了Jane有一只狗的事实.如果这不正确,它会使Jane看起来好像只有一只猫.

如果您开始过滤掉有效数据,则可能需要重新考虑视图的内容以及您尝试使用视图完成的操作.