【问题标题】:MySQL get all associated records where at least one record matches queryMySQL获取至少一条记录与查询匹配的所有关联记录
【发布时间】:2018-07-11 16:44:28
【问题描述】:

我正在尝试让这个 MySQL 搜索查询工作。我希望它返回 firstName、lastName、email 或至少一个 secondaryEmail 与搜索字符串匹配的所有用户。一个用户可以有许多辅助电子邮件。

这是我的 SQL 查询:

SELECT `users`.`id`,
       `users`.`first_name` AS `firstName`,
       `users`.`last_name` AS `lastName`,
       `users`.`email`,
       `usersSecondaryEmails`.`id` AS `usersSecondaryEmails.id`,
       `usersSecondaryEmails`.`email` AS `usersSecondaryEmails.email`
FROM `Users` AS `users`
LEFT OUTER JOIN `UsersSecondaryEmails` AS `usersSecondaryEmails`
        ON `users`.`id` = `usersSecondaryEmails`.`user_id`
WHERE (`users`.`first_name` LIKE '%bob%'
        OR `users`.`last_name` LIKE '%bob%'
        OR `users`.`email` LIKE '%bob%'
        OR `usersSecondaryEmails`.`email` LIKE '%bob%');

此查询成功返回,但是当只有匹配的辅助电子邮件时,它只返回该电子邮件,而不是所有关联的电子邮件。如果找到至少一封辅助电子邮件,我如何更改此查询以返回所有电子邮件?我知道它很可能会有一个包含 EXISTS 的子查询,但我不太确定我会把它放在哪里。

编辑:用户表有名字、姓氏和电子邮件 UsersSecondaryEmails 表有 user_id 和 email

如果用户有 2 封辅助电子邮件(UsersSecondaryEmails 上的“电子邮件”列),并且其中至少有一个与搜索字符串匹配,我希望能找回他们所有的辅助电子邮件。截至目前,这只返回匹配的电子邮件。

【问题讨论】:

  • 您能提供一些示例数据并期待结果吗?
  • 表结构???样本输入???预期输出???这是如何提问的指南。 stackoverflow.com/help/how-to-ask

标签: mysql sql


【解决方案1】:

子查询应该这样做

 SELECT 
       `users`.`id`,
       `users`.`first_name` AS `firstName`,
       `users`.`last_name` AS `lastName`,
       `users`.`email`,
       `usersSecondaryEmails`.`id` AS `usersSecondaryEmails.id`,
       `usersSecondaryEmails`.`email` AS `usersSecondaryEmails.email`
    FROM users users, UsersSecondaryEmails usersSecondaryEmails
    WHERE users.id IN (SELECT user_id FROM UsersSecondaryEmails)
    AND users.id = usersSecondaryEmails.user_id

    AND
    (
    `users`.`first_name` LIKE '%bob%'
    OR
    `users`.`last_name` LIKE '%bob%'
    OR
    `users`.`email` LIKE '%bob%'
    )

【讨论】:

  • 这行得通,但是搜索所有电子邮件像 bob 的电子邮件,然后通过 user_id 匹配的电子邮件来缩小范围不是效率低下吗?应该是相反的
  • 如果可以的话那就太好了
  • 完成。您的评论是正确的。我不是 100% 相信你原来的逻辑。现已修复。
  • 现在它在辅助电子邮件匹配时返回 0 个结果
  • 这会让我相信没有任何符合 '%bob%' 标准的用户的 id 与 usersSecondaryEmails 中的 user_id 匹配。
【解决方案2】:

我相信你想要:

SELECT u.`id`, u.`first_name` AS `firstName`, u.`last_name` AS `lastName`, u.`email`,
       us.`id` AS `usersSecondaryEmails.id`,
       us.`email` AS `usersSecondaryEmails.email`
FROM `Users` u LEFT OUTER JOIN
     `UsersSecondaryEmails` us
     ON u.`id` = us.`user_id`
WHERE (u.`first_name` LIKE '%bob%' OR u.`last_name` LIKE '%bob%' OR u.`email` LIKE '%bob%') OR
      EXISTS (SELECT 1
              FROM `UsersSecondaryEmails` us2
              WHERE us2.user_id = us.user_id AND us2.`email` LIKE '%bob%'
             );

这假设您想要所有第二封电子邮件,即使只有 users 中的字段匹配。如果没有,可以考虑。

【讨论】:

    【解决方案3】:

    您应该使用子查询来避免在 where 中使用与左连接表相关的列(这会产生内部连接)

    SELECT `users`.`id`,
           `users`.`first_name` AS `firstName`,
           `users`.`last_name` AS `lastName`,
           `users`.`email`,
           t.`email` AS `usersSecondaryEmails.email`
    FROM `Users` AS `users`
    LEFT OUTER JOIN (       
        select `usersSecondaryEmails`.`user_id`,  `usersSecondaryEmails`.`email`
        from `UsersSecondaryEmails`
        where `usersSecondaryEmails`.`email` LIKE '%bob%') t on t.`user_id` = `users`.`id 
    where (
    
        `users`.`first_name` LIKE '%bob%'
        OR `users`.`last_name` LIKE '%bob%'
        OR `users`.`email` LIKE '%bob%'
        )
    

    【讨论】:

    • 我收到“字段列表中的未知列 'usersSecondaryEmails.user_id'”错误
    • 它没有修复它。 t 变量来自哪里?
    • t 是子查询的别名。无论如何,您应该添加适当的数据样本和预期结果
    猜你喜欢
    • 1970-01-01
    • 2013-09-27
    • 2014-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-23
    • 2015-04-19
    • 2013-09-24
    相关资源
    最近更新 更多