检查值是不是存在于 2 个表之间

Posted

技术标签:

【中文标题】检查值是不是存在于 2 个表之间【英文标题】:Check values exist and not exist between 2 tables检查值是否存在于 2 个表之间 【发布时间】:2017-09-07 11:32:05 【问题描述】:

我有 3 张桌子,一张是账户,一张是朋友,另一张是消费者。 像这样的:

table_accounts

id | account_name

table_friends

id | account_id | people_id

table_consumers

id | account_id | people_id

我需要交叉以下信息:

两个表中同时存在哪个consumer_id,简单如下:

SELECT 
    *  
FROM
    table_friends,
    table_consumers
WHERE
    table_friend.account_id = 12345
    AND table_friend.account_id = table_consumers.account_id
GROUP BY table_friend.people_id

这个查询很慢

好吧,我现在需要获取consumer_id 的friends 表,这些表不在consumers 表中。在第三个时刻,找出friends 表中不存在哪个consumer_id。但我认为这是同一件事......

我怀疑逻辑,我想不出如何跨越这些信息。

【问题讨论】:

我不懂你的数据库架构,你最后的§不清楚你想要什么,请用你想要的字段名称和表之间的关系编辑你的帖子 【参考方案1】:

这可能或多或少是您尝试做的:(看看Subqueries with EXISTS vs IN - mysql

SELECT *
FROM table_friends
WHERE
    NOT EXISTS (
        SELECT *
        FROM table_consumers
        WHERE table_consumers.people_id = table_friends.people_id
        )

顺便说一句,你说“这个查询很慢”你查询了多少行?什么是“慢”?你有需要它们的索引吗?

【讨论】:

您的示例对我也有很大帮助,因为在使用 NOT IN 时,朋友的示例既能正常工作,又能满足我的需要。非常感谢您的光临【参考方案2】:

你可以这样做吗:

Select a.account_name
, a.id
, case when f.id is null then 0 else 1 end isFriend
, case when c.id is null then 0 else 1 end isConsumer
from table_accounts a
left join table_friends f on a.id = f.account_id
left join table_consumers c on a.id = c.account_id

【讨论】:

这很有趣,因为只返回 1 或 0,但这也很好。谢谢你的时间=)【参考方案3】:

如果我正确理解您的问题,您可以使用 NOT IN 来查找每个表的例外情况。像这样的:

SELECT id  
FROM table_consumers  
WHERE account_id  
NOT IN 
  (SELECT account_id 
   FROM table_friends)

您可以对表名做同样的事情,以找出哪些朋友不在消费者中。如果您想在查询中包含多个表,您可能还需要使用 UNION 或 UNION ALL 进行检查。见:UNION ALL and NOT IN together

【讨论】:

我会把这个放在桌子上***.com/questions/14190788/…,因为它可能是一本好书 伟大的补充Blag!如果 table_consumers 或 table_friends 可能返回空结果 - 使用 NOT IN 可能会导致严重的减速 - 你确实希望按照 Blag 的建议查看 EXISTS。 很好,这个工作很好而且很快。我的表每个都有超过 2M 的记录,但速度慢是因为查询中的一个小错误 :)【参考方案4】:

看起来您已经获得了有关如何编写查询的答案,但您应该考虑重新设计架构。如果还不算太晚。

table_friends 和 table_consumers 都代表人。唯一的区别是什么类型/种类的人。您不希望每次需要向人员添加新属性时都添加新表。 你需要的是:

table_accounts
table_people
table_people_type
table_people_type_mapping 

最后一个是table_peopletable_people_type之间的映射表。 在 table_people_type 中,您现在可以有 friendsconsumers,但您也可以稍后添加不同的类型而无需更改架构。你的查询会更直观。

同样,如果架构更改仍然是您的选择。

【讨论】:

我只是尝试简化系统表以免太混乱,不太复杂的想法可能:) 感谢您的反馈。

以上是关于检查值是不是存在于 2 个表之间的主要内容,如果未能解决你的问题,请参考以下文章

Rails,ActiveRecord,Squeel:检查数组中是不是存在值

检查值是不是存在于数据库行之一中

检查列中的值是不是存在于数据框行中的其他位置

MySQL 检查表是不是已经存在

检查列 pyspark df 的值是不是存在于其他列 pyspark df

检查对象值是不是存在于 Javascript 对象数组中,如果不存在则将新对象添加到数组