查询从2个不同的表中选择和替换记录

时间:2017-12-09 00:00:40

标签: php mysql sql codeigniter

我正在尝试在PHP CodeIgniter中的重复查找程序应用程序中优化某些查询。并且为了保持MVC模式并远离视图或控制器中的DB调用,我正在寻找一个查询,它将从以下两个表中替换结果:

duplicate_leads

╔════╦══════════════╦═══════════╦════════════════════╦═══════════╗
║ id ║ original_id  ║    name   ║       email        ║   phone   ║
╠════╬══════════════╬═══════════╬════════════════════╬═══════════╣
║  1 ║      345     ║   Stack   ║ stack@overflow.com ║ 0000-0000 ║
║  2 ║      495     ║ Exchange  ║ stack@exchange.com ║ 0000-0000 ║
╚════╩══════════════╩═══════════╩════════════════════╩═══════════╝

leads

╔═════╦═══════════╦════════════════════╦═══════════╗
║ id  ║    name   ║       email        ║   phone   ║
╠═════╬═══════════╬════════════════════╬═══════════╣
║ 345 ║   Stack   ║ stack@overflow.com ║ 0000-0000 ║
║ 495 ║ Exchange  ║ stack@exchange.com ║ 0000-0000 ║
╚═════╩═══════════╩════════════════════╩═══════════╝

duplicate_leads.original_id是将潜在客户与原始潜在客户leads.id相关联的值。

尝试#1

SELECT
    a.id,
    a.name,
    a.email,
    a.phone
FROM
    leads a
        JOIN duplicate_leads b
            ON a.id = b.original_id

产生:

╔═════╦═══════════╦════════════════════╦═══════════╗
║ id  ║    name   ║       email        ║   phone   ║
╠═════╬═══════════╬════════════════════╬═══════════╣
║ 345 ║   Stack   ║ stack@overflow.com ║ 0000-0000 ║
║ 495 ║ Exchange  ║ stack@exchange.com ║ 0000-0000 ║
║ ... ║    ...    ║         ...        ║    ...    ║
╚═════╩═══════════╩════════════════════╩═══════════╝

似乎是从两个表中的一个表中检索记录。我没有SQL的高级经验,所以我不知道如何使用这个特殊情况的连接或联合,因为我认为无论哪种方式,查询将返回的是一种结果的连接,如下所示: / p>

╔═════╦═══════════╦════════════════════╦═══════════╗
║ id  ║    name   ║       email        ║   phone   ║
╠═════╬═══════════╬════════════════════╬═══════════╣
║ 345 ║   Stack   ║ stack@overflow.com ║ 0000-0000 ║
║ 495 ║ Exchange  ║ stack@exchange.com ║ 0000-0000 ║
║     ║   Stack   ║ stack@overflow.com ║ 0000-0000 ║
║     ║ Exchange  ║ stack@exchange.com ║ 0000-0000 ║
╚═════╩═══════════╩════════════════════╩═══════════╝

我真正期待的是: 首先显示的行(因为它们可能是多个)应该是leads表中的记录。这些记录应该与original_id的{​​{1}}匹配,这些记录应该是匹配后的下一行,如下所示:

duplicate_leads

多个匹配示例:

╔═════╦═══════════╦════════════════════╦═══════════╗
║ id  ║    name   ║       email        ║   phone   ║
╠═════╬═══════════╬════════════════════╬═══════════╣
║ 345 ║   Stack   ║ stack@overflow.com ║ 0000-0000 ║ from leads
║     ║   Stack   ║ stack@overflow.com ║ 0000-0000 ║ from duplicate_leads
║ 495 ║ Exchange  ║ stack@exchange.com ║ 0000-0000 ║ from leads
║     ║ Exchange  ║ stack@exchange.com ║ 0000-0000 ║ from duplicate_leads
║ ... ║    ...    ║         ...        ║    ...    ║
╚═════╩═══════════╩════════════════════╩═══════════╝

如何实现这一结果?

更新

SQL小提琴:http://sqlfiddle.com/#!9/6d87a9/1

2 个答案:

答案 0 :(得分:1)

你想写这个我相信:

SELECT
a.id,
a.name
a.email
FROM leads a
UNION ALL
SELECT
a.id,
a.name
a.email
FROM leads a
INNER JOIN duplicate_leads b
ON a.id = b.original_id
ORDER BY a.id

第一个查询(在联合之前)将为您的潜在客户表中的每条记录提供一行

第二个查询将为您的重复项表中的每个潜在客户提供一行(假设它在潜在客户表中有匹配 - 如果所有内容都设置正确则应该如此),但会显示记录的信息在找到匹配项的潜在客户表中。

然后,ORDER BY可以帮助您对其进行可视化,以便根据原始潜在客户ID

对所有行进行分组

要记住的重要一点是,连接两个表会创建一个包含两个表中所有列的表(然后使用SELECT修剪哪些列)。使用标准连接时,将保留原始表中的所有字段,如果在第二个表中找到匹配项,则也会填充这些字段。否则,它们将为空。

这就是为什么您的原始查询只为每个潜在客户提供一行。如果您选择*,您将更好地了解幕后发生的事情

答案 1 :(得分:1)

这样的事情:

SELECT id, name, email, phone
FROM (
    SELECT l.id, l.name, l.email, l.phone, dl.original_id
    FROM leads AS l
    JOIN duplicate_leads AS dl
        ON dl.original_id = l.id
    UNION ALL
    SELECT NULL AS id, dl.name, dl.email, dl.phone, dl.original_id
    FROM leads AS l
    JOIN duplicate_leads AS dl
        ON dl.original_id = l.id
) AS leads_combined
ORDER BY original_id ASC, id > 0 DESC, id ASC;

应该更接近你的要求。我已经将我之前的查询与Daniel Long的答案中的JOIN合并,只找到具有重复项的潜在客户,并在结果中的重复项之前对潜在客户进行排序。

相关问题