当我加入主表时,我的视图效果很好:
LEFT OUTER JOIN OFFICE ON CLIENT.CASE_OFFICE = OFFICE.TABLE_CODE.
但是我需要添加以下连接:
LEFT OUTER JOIN OFFICE_MIS ON CLIENT.REFERRAL_OFFICE = OFFICE_MIS.TABLE_CODE
虽然我添加了DISTINCT
,但仍然会收到“重复”的行。我说“重复”,因为第二行有不同的值。
但是,如果我将LEFT OUTER
更改为INNER JOIN
,则会丢失具有这些“重复”行的客户端的所有行。
我做错了什么?如何从我的视图中删除这些“重复”行?
此问题不适用于此情况:
答案 0 :(得分:7)
如果行包含任何不同的列,则DISTINCT将无法帮助您。显然,您要加入的其中一个表在另一个表中的一行中有多行。要获得一行,您必须消除要加入的表中的其他多行。
最简单的方法是增强where子句或JOIN限制,以便只加入你想要的单个记录。通常这需要确定一个规则,该规则总是从另一个表中选择“正确”的条目。
让我们假设您有一个简单的问题,例如:
Person: Jane
Pets: Cat, Dog
如果您在此处创建简单联接,您将收到Jane的两条记录:
Jane|Cat
Jane|Dog
如果您的观点是列出人和宠物的所有组合,这是完全正确的。但是,如果您的观点应该列出有宠物的人,或列出人并展示他们的宠物之一,那么您就会遇到现在的问题。为此,您需要一条规则。
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);
这样做是为了将规则限制在连接中的宠物记录限制为具有最低ID的宠物(在Pets表中的第一个)。 WHERE子句基本上表示“没有宠物属于具有较低ID值的同一个人。”
这将产生一个记录结果:
Jane|Cat
您需要应用于视图的规则取决于您拥有的列中的数据,以及应在列中显示哪些“多个”记录。但是,这最终会隐藏一些数据,这可能不是您想要的。例如,上述规则隐藏了Jane有一只狗的事实。如果这不正确,它会使Jane看起来好像只有一只猫。
如果您要开始过滤掉有效数据,则可能需要重新考虑视图的内容以及您尝试使用视图完成的操作。
答案 1 :(得分:3)
如果第二行有一个不同于它的值,那么它应该被包含在内。
答案 2 :(得分:3)
所以你添加了一个匹配两行的左外连接? OFFICE_MIS.TABLE_CODE在我假设的那个表中不是唯一的吗?您需要将该连接限制为仅抓取一行。这取决于您要查找的行,但您可以执行此类操作...
LEFT OUTER JOIN OFFICE_MIS ON
OFFICE_MIS.ID = /* whatever the primary key is? */
(select top 1 om2.ID
from OFFICE_MIS om2
where CLIENT.REFERRAL_OFFICE = om2.TABLE_CODE
order by om2.ID /* change the order to fit your needs */)
答案 3 :(得分:2)
您可以使用DISTINCT
,而不是使用GROUP BY
。
MIN
/ MAX
/ AVG
或任何其他功能为可以返回多个值的字段提供一个结果。SELECT Office.Field1, Client.Field1, MIN(Office.Field1), MIN(Client.Field2)
FROM YourQuery
GROUP BY Office.Field1, Client.Field1
答案 4 :(得分:1)
您可以尝试使用 Distinct Top 1 ,但正如Hunter指出的那样,如果甚至有一列不同,那么它应该被包含在内,或者如果您不关心或需要该列你应该删除它。任何其他建议可能需要更具体的信息。
编辑:使用 Distinct Top 1 时,您需要通过语句拥有相应的组。你真的会使用 Top 1 部分。区别就在那里,因为如果 Top 1 有一个平局,你将得到一个错误而没有办法避免平局。我见过的两种最常见的方法是将 Distinct 添加到 Top 1 ,或者您可以在查询中添加一个唯一的列,以便sql可以选择哪个记录可以选择一个平局。