连接两个表,一个具有相同的唯一行,另一个具有多个相应的行

时间:2015-09-03 14:27:50

标签: mysql sql ms-access rdms

我有两张桌子,其中一张桌子上有人和包裹信息。此表中的每一行都是唯一的。没有重复数据。它是如下的东西;

enter image description here

此外,我有这个表,其中包括上面显示的这些独特行的说明。例如

enter image description here

正如您所看到的,只有“简”有3种不同的解释。我想将explain1,explanation2,explanation3列添加到第一个表中,并使用第二个表中的相应信息更新这些字段。

然而,问题恰恰出现在那一点上。当我选择让两个表中的Name,Surname,Parcel和Block字段匹配时,所有需要用相关解释更新的解释列都只是用第一个解释来填充。作为示例,第一表的第一行中的“Jane Black”的所有说明1,解释2,解释3字段仅用“Lorem ipsum dolor sit”更新。第二张表中的其余解释仍未使用。

总而言之,我想知道,我处理问题的方式不合理,还是有办法按照我的方法解决这个问题? (我利用访问,mysql作为RDBMS等。)

1 个答案:

答案 0 :(得分:0)

这是一种非常讨厌的方式而且没有经过测试。

这使用3个子查询来获得第1,第2和第3个解释列的必要解释: -

SELECT t1.name, t1.parcel, t1.block, t1.share, t1.id, t2a.explanation, t2b.explanation, t2c.explanation
FROM table1 t1
LEFT OUTER JOIN 
(
    SELECT t21.name, t21.parcel, t21.block, t21.share, t21.id, t21.explanation
    FROM table2 t21
    LEFT OUTER JOIN table2 t22
    ON t21.name = t22.name AND t21.surname = t22.surname AND t21.parcel = t22.parcel AND t21.block = t22.block AND t21.share = t22.share AND t21.id = t22.id AND t1.o > t2.no
    GROUP BY t21.name, t21.parcel, t21.block, t21.share, t21.id, t21.explanation
    HAVING COUNT(t22.No) = 0
) t2a ON t1.name = t2a.name AND t2.surname = t2a.surname AND t1.parcel = t2a.parcel AND t1.block = t2a.block AND t1.share = t2a.share AND t1.id = t2a.id
LEFT OUTER JOIN 
(
    SELECT t21.name, t21.parcel, t21.block, t21.share, t21.id, t21.explanation
    FROM table2 t21
    LEFT OUTER JOIN table2 t22
    ON t21.name = t22.name AND t21.surname = t22.surname AND t21.parcel = t22.parcel AND t21.block = t22.block AND t21.share = t22.share AND t21.id = t22.id AND t1.o > t2.no
    GROUP BY t21.name, t21.parcel, t21.block, t21.share, t21.id, t21.explanation
    HAVING COUNT(t22.No) = 0
) t2b ON t1.name = t2b.name AND t2.surname = t2b.surname AND t1.parcel = t2b.parcel AND t1.block = t2b.block AND t1.share = t2b.share AND t1.id = t2b.id
LEFT OUTER JOIN 
(
    SELECT t21.name, t21.parcel, t21.block, t21.share, t21.id, t21.explanation
    FROM table2 t21
    LEFT OUTER JOIN table2 t22
    ON t21.name = t22.name AND t21.surname = t22.surname AND t21.parcel = t22.parcel AND t21.block = t22.block AND t21.share = t22.share AND t21.id = t22.id AND t1.o > t2.no
    GROUP BY t21.name, t21.parcel, t21.block, t21.share, t21.id, t21.explanation
    HAVING COUNT(t22.No) = 0
) t2c ON t1.name = t2c.name AND t2.surname = t2c.surname AND t1.parcel = t2c.parcel AND t1.block = t2c.block AND t1.share = t2c.share AND t1.id = t2c.id

使用GROUP_CONCAT和SUBSTRING_INDEX比较简单但可靠性稍差。这得到一个用随机字符串分隔的所有解释的字符串(我已经使用了〜#〜##〜这里),然后将其拆分为每列选择不同的一个。如果解释恰好包含用于分隔它的字符串,那么这当然会失败。

SELECT t1.name, 
        t1.parcel, 
        t1.block, 
        t1.share, 
        t1.id, 
        SUBSTRING_INDEX(GROUP_CONCAT(t2.explanation ORDER BY t2.no SEPARATOR '~#~#~'), '~#~#~', 1),
        IF(COUNT(t2.no) >= 2, SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(t2.explanation ORDER BY t2.no SEPARATOR '~#~#~'), '~#~#~', 1), '~#~#~', -1), NULL),
        IF(COUNT(t2.no) >= 2, SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(t2.explanation ORDER BY t2.no SEPARATOR '~#~#~'), '~#~#~', 2), '~#~#~', -1), NULL)
FROM table1 t1
LEFT OUTER JOIN table2 t2
ON t1.name = t2.name AND t2.surname = t2.surname AND t1.parcel = t2.parcel AND t1.block = t2.block AND t1.share = t2.share AND t1.id = t2.id
GROUP BY t1.name, 
        t1.parcel, 
        t1.block, 
        t1.share, 
        t1.id

但我个人可能会在SQL之外的代码中执行此操作。