【问题标题】:SQL - Select TOP 1 from child table with WHERE condition, 2 possible values and 1 is preferredSQL - 从具有 WHERE 条件的子表中选择 TOP 1,2 个可能的值,1 个是首选
【发布时间】:2018-11-16 22:25:24
【问题描述】:

我有 2 个表,父级和一个具有 1-N 关系的子级。

  • Person:ID (INT),名称 (VARCHAR)
  • PersonToCompany:ID (INT)、PersonId (INT)、电子邮件 (Varchar)

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

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

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

现在棘手的部分 - 有些人可以拥有 2 个 PersonToCompany 记录,同时具有 @abc.com@xyz.com 电子邮件域。在这种情况下,我想确保选择带有 @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

【问题讨论】:

    标签: sql sql-server cross-apply


    【解决方案1】:

    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 匹配无论找到哪个电子邮件地址都需要,这对我来说听起来更正确)

    【讨论】:

    • 顺利!我没有看到我可以以这种方式在 ORDER BY 中使用 CASE 。你对括号是对的,当我拼命地尝试查询时,我把它们搞砸了。非常感谢!
    猜你喜欢
    • 2018-04-30
    • 1970-01-01
    • 1970-01-01
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-18
    相关资源
    最近更新 更多