SQL - 从具有WHERE条件的子表中选择TOP 1,2个可能的值,1是首选

时间:2018-06-07 05:56:17

标签: sql sql-server cross-apply

我有2张桌子,父母和一个有1-N关系的孩子。

  • Person:Id(INT),Name(VARCHAR)
  • PersonToCompany:Id(INT),PersonId(INT),电子邮件(Varchar)

我想加入两个表,但只从PersonToCompany表中选择1个记录。我知道我可以使用例如交叉申请,但我也有一些条件。

我想只选择特定的PersonToCompany记录,如下所示:

WHERE (Email LIKE '%@abc.com%' OR Email LIKE '%xyz.com%')

现在是棘手的部分 - 有些人可以在 @ abc.com @ xyz.com 电子邮件域中拥有2条PersonToCompany条记录。在这种情况下,我想确保选择 @ abc.com 的记录。我怎样才能做到这一点?

这是我的原始子查询,选择 @ abc.com @ xyz.com 而没有偏好:

CROSS APPLY (
    SELECT TOP 1 
    PersonToCompany.Email AS Email
    FROM PersonToCompany 
    WHERE PersonToCompany.PersonId = Person.Id
    AND (PersonToCompany.Email LIKE '%@abc.com%') OR (PersonToCompany.Email LIKE '%@xyz.com%')
) PersonToCompany

1 个答案:

答案 0 :(得分:3)

没有TOP 1

ORDER BY是“给我一排,我不关心哪一个”。所以简单的解决方法是添加ORDER BY

CROSS APPLY (
    SELECT TOP 1 
    PersonToCompany.Email AS Email
    FROM PersonToCompany 
    WHERE PersonToCompany.PersonId = Person.Id
    AND (PersonToCompany.Email LIKE '%@abc.com%' OR
         PersonToCompany.Email LIKE '%@xyz.com%')
    ORDER BY CASE WHEN PersonToCompany.Email LIKE '%@abc.com%' THEN 0 ELSE 1 END
) PersonToCompany

(我也改变了一些括号以使逻辑正确,我相信 - 你将个别谓词包括在内,这并没有真正做任何事情。我已经将OR括起来以便PersonId无论找到哪个电子邮件地址都需要1}}匹配,这听起来更正确)