【问题标题】:merging two SELECT queries合并两个 SELECT 查询
【发布时间】:2011-09-27 15:29:51
【问题描述】:

我要么变老了,要么我需要编写的查询变得越来越复杂。以下查询将获取与用户关联的所有tasks

"SELECT `date` 
   FROM `tasks` 
  WHERE `user_id`= 1;"

tasks 表是(iddateuser_idurl_id);

现在,我还需要获取url_id 与用户相关的记录

`urls` table (`id`, `user_id`)

独立查询如下所示:

"SELECT `t1`.`data` 
   FROM `tasks` `t1` 
   JOIN `urls` `u1` ON `u1`.`id` = `t1`.`url_id` 
  WHERE `u1`.user_id` = 1;"

但是,是否可以将这两个查询合并为一个查询?我的逻辑说应该是,虽然我不知道如何进行实际的 JOIN。

【问题讨论】:

  • 您在上次查询中是指data 还是date?另外,如果你没有从 URL 表中选择任何数据,你真的需要加入它吗? (答案可能是“是的,以确保该用户 ID 有一个 URL 条目”。)为什么会有这么多反引号?它和 MS SQL Server 和方括号一样糟糕!
  • 我在途中写了查询,所以我自然没有留下一些错误。不过你是对的,它必须是 date 而不是 data。我通常会忽略关于back-ticks 的评论,尽管您享有很高的声誉,所以我有点好奇您为什么说“它和 MS SQL Server 和方括号一样糟糕”?反引号本身的目的是确保 MySQL 服务器能够快速识别表名和列名,并避免在使用保留关键字时出现混淆,例如嵌套集中的 leftright
  • MS SQL Server 用户对方括号提出了同样的要求。它对我来说看起来很丑,而且完全不标准。没有其他 DBMS 支持 SQL 标准所称的“分隔标识符”的反引号或方括号,该标准称其用双引号括起来;单引号是为字符串保留的。不同的 DBMS 对可以在何处使用关键字有不同的规则。我使用的主要是在许多地方允许关键字作为标识符。最好通过避免将关键字作为标识符来避免使用引号。
  • ...继续...我确实认为您应该更正这个问题。人们不会总是阅读 cmets - 并且不应该阅读 cmets 来理解问题。

标签: mysql sql


【解决方案1】:

我可能会使用UNION

SELECT `date`
   FROM `tasks` WHERE `user_id`=1
UNION
SELECT `t1`.`date`
   FROM `tasks` `t1`
   INNER JOIN `urls` `u1` ON `u1`.`id` = `t1`.`url_id`
   WHERE `u1`.user_id`=1;

【讨论】:

  • 请注意,如果您不想删除重复项,则需要UNION ALL
  • 这很奇怪。我以前从未使用过 UNION,这是过去两天中的第三次。 :) 不过,谢谢!
  • 我当时还不能选择它作为答案,@tvanfosson。
【解决方案2】:

您可以在单个查询中执行此操作:

SELECT t.date
  FROM TASKS t
 WHERE t.user_id = 1
    OR EXISTS(SELECT NULL
                FROM URLS u
               WHERE u.id = t.url_id
                 AND u.user_id = 1)

然而,OR 是一个出了名的糟糕的执行者——它分裂了执行计划。可以使用UNIONUNION ALL 运算符来拆分查询、加入结果集。 UNION 从最终结果集中删除重复项; UNION ALL 不会删除重复项,而且速度更快。

SELECT t.date
  FROM TASKS t
 WHERE t.user_id = 1
UNION ALL
SELECT t.date
  FROM TASKS t
 WHERE EXISTS(SELECT NULL
                FROM URLS u
               WHERE u.id = t.url_id
                 AND u.user_id = 1)

了解您的数据,因此您知道哪个UNION 运营商最能满足您的需求。

【讨论】:

    猜你喜欢
    • 2013-03-28
    • 1970-01-01
    • 1970-01-01
    • 2013-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-24
    相关资源
    最近更新 更多