1

I have code that I've written in an ORM syntax. It reads blog comments data from a file, and inserts them into blogs and comments tables. I'd like to take this ORM code back to mysql, because I need to combine as many queries as possible into a single query, and this optimization wouldn't be easy in the ORM language. The reason I need this optimization is because I'm working with a remote server, so the fewer the queries, the better. I wrote the code below in mysql pseudo-code, because I somewhat forgot mysql.

This is the comments file that contains all the comments for all the blogs. from blog url tells me which blog this comment belongs to.

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

This is the ORM code that I use to process the file. (at the very bottom, I added the description of the tables).

//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();

So my question: is it possible to write this in a single mysql query?

I found a similar question here but it doesn't fully solve my problem, and I'm not sure if it's the most efficient way to do it.

The 2 tables are blogs and comments where each row in comments has a field blogid that links it to the right blog in blogs. So it's basically a 1:many relationship where each blog row can be linked to many comment rows. They look like this:

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
Community
  • 1
  • 1
sameold
  • 18,400
  • 21
  • 63
  • 87
  • TO insert into two tables do you need at least two sql statements (one by table). Do you know it? Otherwise, a store procedure or trigger is needed. Is a procedure or trigger a valid solution for you? – dani herrera Aug 25 '12 at 18:20
  • @danihp my main goal is to contact that database server once if possible. So I'm OK with anything that helps me do that. – sameold Aug 25 '12 at 18:27
  • @danihp I should point out that the 2 queries I'm trying to combine are related, but not identical. The second query just uses the `blog_id` from the first query. – sameold Aug 25 '12 at 18:31

1 Answers1

3

You can use this technique to insert a row if not exists:

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

As you can see, select clause will return a only one row with data to be inserted only when not yet exists in database. You can test it at SQLFIDDLE.

To insert into comment table you can use same technique. You can get Blog id for second query with LAST_INSERT_ID() if inserted is dued (if not, you need a new query).

This is only a point to start, perhaps you can reduce to 3 your 4 queries. Any comment are welcome to figure up final solution.

As you know, MySQL don't has MERGE statement. I think that replace don't match your requeriments.

dani herrera
  • 48,760
  • 8
  • 117
  • 177
  • I'm wondering, what is `from dual` Is this a misnamed table, or a special keyword? – sameold Aug 25 '12 at 18:49
  • So is it possible to further nest the comment insertion, so that both blog insertion and comment insertion are in the same query? – sameold Aug 25 '12 at 18:51
  • YOu need a insert statement for each table. You can't do both inserts in the same statement. Perhaps do you want to encapsulate all code into a [store procedure](http://www.mysqltutorial.org/mysql-stored-procedure-tutorial.aspx). – dani herrera Aug 25 '12 at 20:03