【问题标题】:How to remove matches between unioned tables with joined tables如何删除联合表与连接表之间的匹配项
【发布时间】:2019-02-14 04:58:35
【问题描述】:

我有两张桌子

电子邮件和字段

emails 只是一个电子邮件列表,它们的唯一标识符和字段采用第五范式(我认为),具有一列值(第二列中的 ID 数据)、一个数据列和链接到uuids 在第一个表中。

例如:

表 1:

ID    EMAIL    
--    -----  
1a2  Test@Test   
2a3   email@email|
3a4   add@add    

表 2:

value     Data        ID 
-----    ------       ---
 1       123 Main     1a2
 2      John Smith    1a2
 3         US         1a2  
 4     555-555-5555   1a2  

在这种情况下,表 2 仅显示“1a2”的数据,因为它们是唯一填写它们的数据。

所以我正在尝试制作一个表格,将电子邮件与相应的国家/地区代码结合起来,并提供尚未将国家/地区代码注册为 Null 值的电子邮件

在将表 1 和 2 加入 ID 后,我尝试使用 UNION 在表 2 上显示来自表 1 的所有电子邮件,然后使用 where 作为值,但它显示了所有具有正确国家代码的电子邮件,然后重复它们也在 UNIONed 部分中。

这是我得到的一个例子:

EMAIL        COUNTRY CODE
-----        ------------
test@test        US
test@test        NULL
email@email      NULL
add@add          NULL

您会注意到 test@test 由于联合没有正确的过滤器而重复

我的代码如下:

select
    e.email as "Email",
    f.value as "Country Code"
from
    email e
join
    fields f
    ON e.id = f.id
where
    f.value = '3'
    [[and f.data like concat({{CountryCode}},'%')]]   
    -- curly brackets are for user entered variables

无论如何,一切都说了算。我正在寻找一个看起来像这样但没有重复的表格

EMAIL        COUNTRY CODE
-----        ------------
test@test        US
email@email      NULL
add@add          NULL

【问题讨论】:

    标签: mysql union matching metabase


    【解决方案1】:

    您正在以键值格式存储用户元数据。这里的一种方法是将用户表左连接到一个子查询,该子查询以查找国家为中心:

    SELECT
        e.EMAIL,
        f.country_code
    FROM email e
    LEFT JOIN
    (
        SELECT ID, MAX(CASE WHEN value = 3 THEN Data END) AS country_code
        FROM fields
        GROUP BY ID
    ) f
        ON e.ID = f.ID;
    

    Demo

    【讨论】:

      【解决方案2】:

      您可以尝试使用max() 聚合和分组 -

      select
          e.email as "Email",
          max(f.value) as "Country Code"
      from
          email e
      left join
          fields f
          ON e.id = f.id
      where
          f.value = '3'
          [[and f.data like concat({{CountryCode}},'%')]]   
      group by  e.email
      

      【讨论】:

      • 这将过滤掉没有国家代码条目的用户。如果您想坚持目前的方法,请考虑 using this version
      【解决方案3】:

      您可以将您感兴趣的字段作为 LEFT JOIN 条件的一部分。

      SELECT
          e.EMAIL,
          f.data as countryCode
      FROM email e
      LEFT JOIN fields f ON f.value=3 AND e.ID=f.ID
      

      具有该字段值的用户将返回它。没有的用户将简单地为 NULL,因为它是一个 LEFT 连接。

      如果你想对字段值做一个条件,那么你还需要包括一个空检查。

      SELECT
          e.EMAIL,
          f.data as countryCode
      FROM email e
      LEFT JOIN fields f ON f.value=3 AND e.ID=f.ID
      WHERE
          f.data IS NULL 
          OR f.data='US'
      

      【讨论】:

        【解决方案4】:

        好吧,我在发布后感觉很傻,但我找到了解决方案,并将发布它以防其他人遇到问题。

        left join
            fields f
            ON e.id = f.id
        where
            f.value = '3' OR f.value is null
            [[and f.data like concat({{CountryCode}},'%')]]
        

        我只需要为空值添加一个“OR”。抱歉,如果我浪费了任何人的时间,我显然是把事情复杂化了,并设法在没有工会的情况下实现了我想要做的事情。

        【讨论】:

        • 如果电子邮件包含某些字段的记录但没有“3”字段的记录,则此查询将无法正常工作。 example
        • 正确,但是在我的情况下,所有字段都是必需的,所以我想这对我来说不是问题。基本上,电子邮件要么具有所有值,要么没有值。我正在尝试查看所有电子邮件,无论它们是否具有值,但还要查看附加的国家/地区代码,在没有显示国家/地区代码的电子邮件中没有重复。
        猜你喜欢
        • 2021-04-26
        • 2013-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-12
        相关资源
        最近更新 更多