查询以返回相关行对,但仅在两个行都存在时才返回

时间:2012-12-20 16:15:13

标签: c# asp.net sql-server database

我有以下表格:

  

* sistema_documentos *

     

[id],[caminho],[idDocType](FK - > sistema_DocType.id)

     

* sistema_Indexacao *

     

[id],[idDocumento](FK - > sistema_documentos.id),[idIndice](FK - >   sistema_Indexes),[valor]

     

* sistema_DocType *

     

[id],[tipoNome](FK - > sistema_DocType.id)

     

* sistema_DocType_Index *

     

[id],[idName],[mask],[idTipo](FK - > sistema_DocType.id),[tamanho]

来自此查询

select distinct a.id, b.idIndice, b.valor from tgpwebged.dbo.sistema_Documentos as a
join tgpwebged.dbo.sistema_Indexacao as b on a.id = b.idDocumento
join tgpwebged.dbo.sistema_DocType as c on a.idDocType = c.id
join tgpwebged.dbo.sistema_DocType_Index as d on c.id = d.docTypeId
where d.docTypeId = 40 
and (b.idIndice = 11 AND b.valor = '11111111' OR b.idIndice = 12 AND b.valor = '22222' )

我得到以下结果

id  idIndice    valor
13  11          11111111
13  12          22222
14  11          11111111
14  12          22222
16  12          22222

正如你所看到的,我希望idIndice 11的所有id值为11111111,12值为22222

Id 16的id为12,值为22222 authough它没有id 11,值为11111111所以我不希望它显示出来。

如何更新我的查询以获得我想要的结果。希望我的问题很明确。如果它不只是问我和我编辑我的帖子。感谢

2 个答案:

答案 0 :(得分:1)

我会建议这样的事情:

WITH TempTable AS 
( 
    select distinct a.id, b.idIndice, b.valor  
    from tgpwebged.dbo.sistema_Documentos as a  
        join tgpwebged.dbo.sistema_Indexacao as b on a.id = b.idDocumento 
    join tgpwebged.dbo.sistema_DocType as c on a.idDocType = c.id
    join tgpwebged.dbo.sistema_DocType_Index as d on c.id = d.docTypeId 
    where d.docTypeId = 40      
        and (b.idIndice = 11 AND b.valor = '11111111' OR b.idIndice = 12 AND b.valor = '22222' ) 
)

SELECT *  
FROM TempTable t1 
WHERE (select count(*)          
       from TempTable t2        
       where t1.id = t2.id AND t1.valor != t2.valor) = 1

所以...从第一个查询中获取所有结果,其中至少有一个结果来自与id匹配的表,但在valor上不匹配。 (这假设您可以使用相同的值来重复行,但您不希望这样。)

答案 1 :(得分:0)

尝试这样的事情。我拿出了与查询没有直接关系的表,虽然我对它们进行了类似的命名,但我创建了一个简单的模式来复制问题。我希望这很清楚,并且回到原始查询的连接同样清楚。

CREATE TABLE Documentos (ID INT, document varchar(12))
create table Indexacao (AID INT, indice int, valor varchar(12))

insert Documentos(id, document)
values (1, 'test1'),
        (2, 'test2'),
        (3, 'test3')

insert Indexacao (aid, indice, valor)
values (1, 11, '11111111'),
        (1, 12, '22222'),
        (2, 12, '22222')

代码的重要部分是INTERSECT - 它只返回两个集合中的行。根据我的经验,此运算符通常比包含OR的任何运算符更有效。在下面的查询中,我们只获得那些idDocumentos在两组条件的INTERSECT中的Indexacao行。

SELECT Ind.*
FROM Indexacao Ind
JOIN (
    SELECT  D.ID
    FROM    Documentos  D
    JOIN    Indexacao   I
    ON      D.ID = I.AID
    WHERE   I.Indice = 11 AND I.valor = '11111111'
    INTERSECT
    SELECT  D.ID
    FROM    Documentos  D
    JOIN    Indexacao   I
    ON      D.ID = I.AID
    WHERE   I.Indice = 12 AND I.valor = '22222'
    )Doc (ID)
ON  Doc.ID = Ind.AID    

这假设您没有单个idDocumento的重复Indice,Valor行 - 如果您这样做,则需要添加DISTINCT。