SQL 在 table 行之间加入

SQL join between table rows

我的 sql 查询有问题,对我来说这看起来很简单,但无法正常工作。

所以我有这个 table:

broadcast_media_id 告诉我数据是 1 - 电子邮件还是 2 - phone。我需要为一名员工收集电子邮件和 phone(具有相同的 employee_id)。

我试过的查询是这样的:

SELECT DISTINCT ed.employee_id,
    ed.text_value AS email,
    x.text_value AS phone
FROM employee_data ed
    INNER JOIN
        (
            SELECT employee_id,
                text_value
            FROM employee_data
            WHERE broadcast_media_id = 2
        ) x ON x.employee_id = ed.employee_id
WHERE broadcast_media_id = 1

不幸的是,由于 WHERE 子句,我仅在员工有电子邮件时才获取值。所以结果是这样的:

我错过了 "A773B230-754C-423F-97C4-E331268EA3C8" 的 phone 值,只是因为他没有电子邮件。我也想显示这一行,并且电子邮件的值为 NULL。

我觉得很简单,但我想不通。

感谢您的帮助。

如果员工总是 phone,只需使用 LEFT JOIN。

SELECT DISTINCT ed.employee_id,
    ed.text_value AS email,
    x.text_value AS phone
FROM employee_data ed
    LEFT JOIN
        (
            SELECT employee_id,
                text_value
            FROM employee_data
            WHERE broadcast_media_id = 2
        ) x ON x.employee_id = ed.employee_id
WHERE broadcast_media_id = 1

你也可以避免自连接,但很可能性能会更差

SELECT ed.employee_id,
        MIN(CASE WHEN broadcast_media_id = 1 THEN text_value END) AS phone,
        MIN(CASE WHEN broadcast_media_id = 2 THEN text_value END) AS email
FROM employee_data ed
GROUP BY ed.employee_id

如果员工可以没有 phone 那么你可以使用 FULL JOIN

SELECT DISTINCT
    COALESCE(ed.employee_id, x.employee_id) employee_id,
    ed.text_value AS email,
    x.text_value AS phone
FROM
    (SELECT * FROM employee_data WHERE broadcast_media_id = 1) ed
    FULL JOIN (SELECT * FROM employee_data WHERE broadcast_media_id = 2) x
        ON x.employee_id = ed.employee_id;

如果你想使用join,你可以使用LEFT JOIN:

SELECT ed.employee_id, ede.text_value AS email,
       edp.text_value AS phone
FROM employees e LEFT JOIN
     employee_data ede
     ON ede.employee_id = e.employee_id AND
        ede.broadcast_media_id = 1 LEFT JOIN
     employee_data edp
     ON edp.employee_id = e.employee_id AND
        edp.broadcast_media_id = 2

注意:这假设您有一个 employees table -- 这看起来很合理。这对于 LEFT JOIN 来说非常方便。这可能会有最好的性能。

如果您没有 employees table,则使用子查询 (SELECT DISTINCT employee_id FROM employee_data)

我倾向于使用条件聚合来执行此操作,它也应该具有合理的性能。

试试这个查询——虽然我没有使用任何连接

Select
    EmpID,
    Max(Case When MediaID = 1 Then TextValue End) As EmailID,
    Sum(Case When MediaID = 2 Then Cast(TextValue As Int) End) As PhoneNumber
From employee_data
Group By EmpID
Order By EmpID;

此处 - 分拣成本 ​​= 78%,Table 扫描成本 = 22%。 (我的实例数据,它肯定会因您的系统和数据而异。)

如果你做一些索引,那么它会表现得更好。

我会使用双 LEFT JOIN,例如:

    SELECT ed.employee_id
          ,COALESCE(ed1.text_value,'') as mail
          ,COALESCE(ed2.text_value,'') as phone
      FROM employee_data ed
 LEFT JOIN employee_data ed1
        ON ed.employee_id = ed1.employee_id
       AND ed1.broadcast_media_id = 1
 LEFT JOIN employee_data ed2
        ON ed.employee_id = ed2.employee_id
       AND ed2.broadcast_media_id = 2