【问题标题】:Left join to a table which may or not contain the data左连接到可能包含或不包含数据的表
【发布时间】:2018-09-16 15:06:39
【问题描述】:

我有以下表格:客户和商店。 他们有以下列:

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

商店:ID、名称、ClientId

ClientId 是表 Client 的外键。

我需要根据姓名 AND surname OR Email 进行搜索,如果 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 如果表 Shop 中有任何包含这些详细信息的条目,请将其返回,但不包括 ID 为 201 的客户。

我也想将此 SQL 转换为 LinQ。

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

【问题讨论】:

  • 为什么ShopClientId?这意味着一个客户有 0..n 个商店,而一个商店只有 1 个客户。我希望这种关系是多对多的,即使用联结表。
  • 样本数据和期望的结果真的很有帮助。
  • 也许我的SQL to LINQ Recipe 可以帮助你。

标签: sql sql-server linq


【解决方案1】:

我不确定我是否完全理解了这个要求。我正在写 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 查询。不过还是自己写吧。

【讨论】:

    【解决方案2】:

    使用内连接而不是左连接并使用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'
    

    【讨论】:

    • 如果我使用内连接,如果 Shop 表中没有记录,请求将不会返回任何数据
    • @tabby 所以你想在商店没有数据的情况下返回数据吗?
    • 是的,如果表Shop中有数据,它应该返回它。否则仅返回在 Client 表中找到的那些。
    • 你知道为什么左连接在这里不起作用吗?
    【解决方案3】:

    似乎您需要执行 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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-16
      • 2016-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-23
      相关资源
      最近更新 更多