将多个查询组合成一个查询

Posted

技术标签:

【中文标题】将多个查询组合成一个查询【英文标题】:Combining multiple queries into a single query 【发布时间】:2012-08-25 18:15:04 【问题描述】:

我有我用 ORM 语法编写的代码。它从文件中读取博客 cmets 数据,并将它们插入到 blogscomments 表中。 我想把这个 ORM 代码带回 mysql,因为我需要将尽可能多的查询组合成一个查询,而这种优化在 ORM 语言中并不容易。我需要这个优化的原因是因为我正在使用远程服务器,所以查询越少越好。我用mysql伪代码编写了下面的代码,因为我有点忘记了mysql。

这是包含所有博客的所有 cmets 的 cmets 文件。 from blog url 告诉我这条评论属于哪个博客。

comment text               from blog url
------------------------------------------
first comment text         first-blog-url
second comment text        first-blog-url
third comment text         first-blog-url
fourth comment text        blog-2-url
fifth comment text         blog-2-url
sixth comment text         3rd-blog-url

这是我用来处理文件的 ORM 代码。 (在最底部,我添加了表格的描述)。

//I read a comment from the comments file, `comment text` and `from blog url`

//does a blog exist that has 'link' that matches 'from blog url'
$blog = //SELECT FROM blogs where 'link' has value 'first-blog-url'

//if it doesn't exist, create it
if($blog == null)
    $blog = INSERT INTO blogs a new record and set 'link' to 'first-blog-url'


//then read the id of the (existing or just-created) blog row
$blog_id = $blog->getId();

//then use the $blog_id to insert the comment into the 'comments' table.

//does this comment text already exist for this blog id?
$comment = SELECT FROM comments where `commenttext' has value 'whatever comment text' and 'blogid' has value $blog_id

//if it doesn't exist, create it
if($comment == null)
    $comment = INSERT INTO comments a new record and set 'commenttext' to 'the comment text' and 'blogid' to $blog_id.


$comment_id = $comment->getId();

所以我的问题是:是否可以在单个 mysql 查询中编写它?

我发现了一个类似的问题here,但它并没有完全解决我的问题,我不确定这是否是最有效的方法。

这两个表是blogscomments,其中comments 中的每一行都有一个字段blogid,该字段将其链接到blogs 中的正确博客。所以它基本上是一个 1:many 关系,其中每个 blog 行可以链接到许多 comment 行。它们看起来像这样:

blogs:

id        link                  other fields
--------------------------------------------
1         first-blog-url
2         blog-2-url
3         3rd-blog-url

comments:

id        commenttext     blogid
-----------------------------
1         random          1
2         comment         1
3         goes            1
4         here            2
5         any             2 
6         thing           3

【问题讨论】:

要插入两个表,您是否需要至少两个 sql 语句(一个按表)。你知道吗?否则,需要存储过程或触发器。程序或触发器对您来说是有效的解决方案吗? @danihp 我的主要目标是尽可能联系该数据库服务器一次。所以我可以接受任何可以帮助我做到这一点的事情。 @danihp 我应该指出,我试图组合的 2 个查询是相关的,但并不完全相同。第二个查询只使用第一个查询中的blog_id 【参考方案1】:

如果不存在,您可以使用此技术插入行:

INSERT INTO blogs (link)
select 'first-blog-url' 
from dual
where not exists
( select 1
  from blogs
  where  link = 'first-blog-url'
);

如您所见,select 子句将仅返回一行,其中仅当数据库中尚不存在数据时才插入数据。 You can test it at SQLFIDDLE.

要插入comment 表,您可以使用相同的技术。如果插入到期,您可以使用LAST_INSERT_ID() 获取Blog id 进行第二次查询(如果没有,您需要一个新查询)。

这只是一个开始点,也许您可​​以将 4 个查询减少到 3 个。欢迎任何意见以找出最终解决方案。

如您所知,MySQL 没有 MERGE 语句。我认为replace 不符合您的要求。

【讨论】:

我在想,from dual 是什么?这是一个错误命名的表,还是一个特殊的关键字? 那么是否可以进一步嵌套评论插入,使博客插入和评论插入都在同一个查询中? 您需要为每个表添加一个插入语句。您不能在同一语句中同时执行两个插入操作。也许您想将所有代码封装成store procedure。

以上是关于将多个查询组合成一个查询的主要内容,如果未能解决你的问题,请参考以下文章

组合查询

组合查询

将多个分组查询组合成单个查询

将多个mysql查询组合成一个结果

将多个 SQL 查询组合成单个结果

第十七章 组合查询