在sql server中连接的额外行

时间:2013-01-31 17:55:22

标签: sql

此查询:

select distinct a.id, a.caminho, c.indexObr, d.id, d.tamanho, d.mask, d.idName
from gedaidb.dbo.sistema_Documentos as a
join gedaidb.dbo.sistema_DocType as b on a.idDocType = b.id
join gedaidb.dbo.sistema_DocType_Index as c on b.id = c.docTypeId
join gedaidb.dbo.sistema_Indexes as d on c.indexId = d.id
join gedaidb.dbo.sistema_Indexacao as e on a.id = e.idDocumento
where a.id = 97

返回此resultSet:

id  caminho                                                     indexObr    id  tamanho    mask     idName
97  C:\Users\Guilherme\Desktop\Guilherme\Tipo 3\SkypeSetup.exe  0           25  10         NULL     Numérico
97  C:\Users\Guilherme\Desktop\Guilherme\Tipo 3\SkypeSetup.exe  0           26  10         NULL     AlfaNumérico
97  C:\Users\Guilherme\Desktop\Guilherme\Tipo 3\SkypeSetup.exe  1           24  10         NULL     Caracter

现在如果我在查询中添加e.valor:

select distinct a.id, a.caminho, c.indexObr, d.id, d.tamanho, d.mask, d.idName, e.valor
from gedaidb.dbo.sistema_Documentos as a
join gedaidb.dbo.sistema_DocType as b on a.idDocType = b.id
join gedaidb.dbo.sistema_DocType_Index as c on b.id = c.docTypeId
join gedaidb.dbo.sistema_Indexes as d on c.indexId = d.id
join gedaidb.dbo.sistema_Indexacao as e on a.id = e.idDocumento
where a.id = 97

我得到了那些返回的行:(唯一的额外列是最后一个,勇敢的)

97  C:\Users\Guilherme\Desktop\Guilherme\Tipo 3\SkypeSetup.exe  0   25  10  NULL    Numérico    11111
97  C:\Users\Guilherme\Desktop\Guilherme\Tipo 3\SkypeSetup.exe  0   25  10  NULL    Numérico    aaaa111
97  C:\Users\Guilherme\Desktop\Guilherme\Tipo 3\SkypeSetup.exe  0   25  10  NULL    Numérico    ccccc
97  C:\Users\Guilherme\Desktop\Guilherme\Tipo 3\SkypeSetup.exe  0   26  10  NULL    AlfaNumérico    11111
97  C:\Users\Guilherme\Desktop\Guilherme\Tipo 3\SkypeSetup.exe  0   26  10  NULL    AlfaNumérico    aaaa111
97  C:\Users\Guilherme\Desktop\Guilherme\Tipo 3\SkypeSetup.exe  0   26  10  NULL    AlfaNumérico    ccccc
97  C:\Users\Guilherme\Desktop\Guilherme\Tipo 3\SkypeSetup.exe  1   24  10  NULL    Caracter    11111
97  C:\Users\Guilherme\Desktop\Guilherme\Tipo 3\SkypeSetup.exe  1   24  10  NULL    Caracter    aaaa111
97  C:\Users\Guilherme\Desktop\Guilherme\Tipo 3\SkypeSetup.exe  1   24  10  NULL    Caracter    ccccc

所有加入的表都有1-N关系,所以据我所知,如果没有N-N关系我不应该得到那些额外的行

这个问题背后的理论是什么?

2 个答案:

答案 0 :(得分:0)

除非你在e.valor上放置一个聚合函数(min,max等),否则将表'e'转换为一个派生表,它将与表'a'建立一对一的关系,那么你得到的结果集是正确的 - e.valor使这些行彼此不同/ distinct

gedaidb.dbo.sistema_Indexacao(表'e')显然(至少)与gedaidb.dbo.sistema_Documentos(表'a')的一对多关系。因此,当您在e.valor(或表e中的任何其他字段)中引入不同的值时,您应该预见到您所看到的“很多”效应。

答案 1 :(得分:0)

如果提供了表创建/插入语句,那么我们就试一试sqlfiddle。尽管如此,尝试一下: - (仅限测试和逻辑,因此请测试并评论)

注意:您可以根据需要调整x.r条件和order by字段中的row_number()

select x.id, x.caminho, x.indexObr, x.id, x.tamanho, x.mask, x.idName, x.valor
from      
(     
    SELECT  a.id, a.caminho, c.indexObr, d.id, d.tamanho, d.mask, d.idName, e.valor
    row_number() over ( partition by b.val3 e.valor                 
    order by a.id, a.caminho, c.indexObr, d.id, d.tamanho, d.mask, d.idName) r     
    from gedaidb.dbo.sistema_Documentos as a
    join gedaidb.dbo.sistema_DocType as b on a.idDocType = b.id
    join gedaidb.dbo.sistema_DocType_Index as c on b.id = c.docTypeId
    join gedaidb.dbo.sistema_Indexes as d on c.indexId = d.id
    join gedaidb.dbo.sistema_Indexacao as e on a.id = e.idDocumento
    where a.id = 97    
) x     
where x.r > 1 --