【问题标题】:Need Optimized Query which take data from three tables需要从三个表中获取数据的优化查询
【发布时间】:2013-03-13 12:21:22
【问题描述】:

三个表

accounts, products, users
  1. 从用户表中选择用户 ID 和电子邮件,其中有 ID 帐户
  2. 然后从用户所在的产品表中过滤掉它们 购买超过 3 件产品 (需要统计产品表中的用户,如果他的数量超过3,则排除用户)。

       SELECT id, email
    FROM  users 
    WHERE id
    IN (
    SELECT user_id
    FROM accounts
    WHERE users.id = user_id
    )
    

我得到了所有用户 ID 和电子邮件,但现在我需要从产品表中过滤掉它们。在产品表中,我有“product_id”和“leader_id”,这是用户 ID。

我需要优化查询,因为表很大

【问题讨论】:

  • 信息不足。我们不知道这些表是如何关联的。我们不知道表上是否存在任何索引来提高性能,也不知道您尝试了什么。
  • 正是......向我们展示一些示例数据或您的表结构;)
  • @javier 这是一个很大的飞跃。你假设每个表都有一个名为 ID 的字段,我推断它是指他们的主键,可能是 Account_ID、Product_ID、User_ID 或者可能只是“ID”,我问的原因是模棱两可。
  • users 表:列是,id 和 email。帐户表:id 和 user_id。并在产品表列中:id、product_id 和 leader_id

标签: mysql query-optimization


【解决方案1】:

我有点明白...这样的东西应该可以工作:

 select u.id,u.mail,
 (select count(1) 
   from products
  where products.leader_id = u.id)
 as conteo
 from user u
  left join account ac
 on(u.id = ac.user_id)
 having (conteo>3)

希望对你有帮助;)

感谢。

【讨论】:

    【解决方案2】:

    如果您需要优化查询,请提供您的架构的正确详细信息 - 表、数据类型和索引。

       SELECT id, email
       FROM  users 
       WHERE id
       IN (
          SELECT user_id
          FROM accounts
          WHERE users.id = user_id
       )
    

    除非万不得已,否则切勿使用子查询。由于您不想要帐户表中的任何数据,因此在大多数 DBMS 中,“EXISTS (SELECT 1 FROM accounts WHERE users.id=user_id)”会更有效——但在未优化的 MySQL 中则不会推谓词。

    查询应该是:

    SELECT DISTINCT u.id, u.email
    FROM users u INNER JOIN accounts a 
    ON u.id=a.user_id;
    

    从用户购买超过 3 个产品的产品表中退出

    虽然我可以猜到足以重写您之前的查询的架构,但我不知道 products 表的结构,事实上,“products”意味着项目目录,并且与帐户的关系似乎是n:m 意味着必须有一个丢失的表来分解关系。此外,根据您的描述,帐户数据独立于“产品”表数据(这看起来很奇怪)。是否要包括用户在“产品”中没有相关记录的情况?

    假设情况并非如此,并猜测结构可能是什么......

    SELECT u.id, u.email, SUM(IF(leader_id IS NULL, 0, amount))
    FROM users u INNER JOIN accounts a 
    ON u.id=a.user_id
    LEFT JOIN product p
    ON u.id=p.leader_id
    GROUP BY u.id, u.email;
    

    我需要优化查询,因为表很大

    为什么需要在一个查询中查看所有数据?

    【讨论】:

    • 很好的查询,但不排除购买超过3次的用户。在leader_id 列中的产品中有id。我需要排除所有购买产品超过 3 次的用户
    • 哎呀 - 在故事中有点迷失了 - 在末尾添加 'HAVING SUM(IF(leader_id IS NULL, 0, amount))
    猜你喜欢
    • 1970-01-01
    • 2011-04-25
    • 2014-02-15
    • 1970-01-01
    • 2023-03-07
    • 2012-07-21
    • 1970-01-01
    • 2016-02-02
    相关资源
    最近更新 更多