左联接到可能包含或不包含数据的表

时间:2018-09-16 15:06:39

标签: sql sql-server linq

我有下表:客户和商店。 它们包含以下列:

  

客户:ID,姓名,姓氏,电子邮件

     

商店:ID,名称,客户ID

ClientId是表Client的外键。

我需要根据姓名和姓氏或电子邮件进行搜索,如果Shop表中有任何条目,则将其返回 但不应返回作为参数传递的ID。

我尝试如下使用左联接,但这不起作用:

select *
from Client c 
left join Shop s
on c.Id  = s.ClientId
where c.Name = 'abc'
and c.Surname = 'xyx'
and c.Id != Id
or c.Email = 'ab@cde.com'
and c.Id != Id

但这不会返回正确的数据。

例如,我想用电子邮件命名乔恩(Jon)和姓萨姆(Sam) jon@samy.com和clientId =201。
因此,该请求应退回所有具有Jon姓氏Sam或电子邮件jon@samy.com的客户 并且如果在“商店”表中有任何包含这些详细信息的条目,则将其返回,但不包括ID为201的客户。

我也想将此SQL转换为LinQ。

知道我的请求出了什么问题吗?

3 个答案:

答案 0 :(得分:0)

使用内部联接而不是左联接,并使用or条件,并在店中没有数据的情况下根据需要从客户端添加数据联合

    select c.*
    from Client c 
    inner join Shop s
    on c.Id  = s.ClientId
    where c.Name = 'abc'
    or c.Surname = 'xyx'
    or c.Email = 'ab@cde.com'
   union
   select * from Client c
   where c.Name = 'abc'
    or c.Surname = 'xyx'
    or c.Email = 'ab@cde.com'

答案 1 :(得分:0)

好像您需要做一个EXISTS而不是LEFT JOIN,因为可能有一个客户出现在不同的商店中:

select *
from Client c
where exists(
    select * from Shop s
    where c.Id = s.clientid
)
    and c.Name = 'Jon'
    and c.Surname = 'Sam'
    and c.Id <> 201

如果您坚持使用LOJ:

select *
from Client c
left outer join Shop s
    on c.Id = s.ClientId
where s.Id is not null
    and c.Name = 'Jon'
    and c.Surname = 'Sam'
    and c.Id <> 201

LINQ:

var searchResult = from c in clients
               where shops.Any(s => s.ClientId == c.Id)
                   && c.Name.Equals("Jon")
                   && c.Surname.Equals("Sam")
                   && c.Id != 201
               select c;

答案 2 :(得分:0)

我不确定我是否完全理解该要求。我正在写2个查询。其中一种应该适合您的情况

如果要排除ID的商店条目,但要客户条目

SELECT * FROM Client c 
LEFT JOIN (SELECT * FROM Shop WHERE ClientId != Id) s ON c.Id  = s.ClientId
WHERE (c.Name = 'abc' AND c.Surname = 'xyx') OR (c.Email = 'ab@cde.com')

如果您要排除客户条目

SELECT * FROM Client c 
LEFT JOIN Shop s ON c.Id  = s.ClientId
WHERE (c.Name = 'abc' AND c.Surname = 'xyx' AND c.Id != Id) OR (c.Email = 'ab@cde.com' AND c.Id != Id)

如果有效,请告诉我。我将帮助您进行LINQ查询。但是请尝试自己编写。